From f16aa260866eea34eff5b62c9877aa84449785f5 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Fri, 24 Jul 2026 00:28:46 +0200 Subject: [PATCH 1/5] v0.12.81 --- package.json | 2 +- version.edn | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 33263aa..dafecf0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@babashka/cli", - "version": "0.12.80", + "version": "0.12.81", "description": "Turn functions into command line interfaces.", "exports": { ".": "./index.mjs" diff --git a/version.edn b/version.edn index 99d0a06..7b24e33 100644 --- a/version.edn +++ b/version.edn @@ -1 +1 @@ -{:major 0, :minor 12, :release 80} \ No newline at end of file +{:major 0, :minor 12, :release 81} \ No newline at end of file From 63600c9b8e91bca80a0fbf7b1d591c86cf6307bb Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Fri, 24 Jul 2026 17:59:04 +0200 Subject: [PATCH 2/5] v0.12.82 --- package.json | 2 +- version.edn | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index dafecf0..69a1d67 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@babashka/cli", - "version": "0.12.81", + "version": "0.12.82", "description": "Turn functions into command line interfaces.", "exports": { ".": "./index.mjs" diff --git a/version.edn b/version.edn index 7b24e33..a358a7e 100644 --- a/version.edn +++ b/version.edn @@ -1 +1 @@ -{:major 0, :minor 12, :release 81} \ No newline at end of file +{:major 0, :minor 12, :release 82} \ No newline at end of file From 32dd3b38a8bdd1960c5241471c43513161dff736 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Sun, 26 Jul 2026 15:28:59 +0200 Subject: [PATCH 3/5] v0.12.83 --- package.json | 2 +- version.edn | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 69a1d67..414c67c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@babashka/cli", - "version": "0.12.82", + "version": "0.12.83", "description": "Turn functions into command line interfaces.", "exports": { ".": "./index.mjs" diff --git a/version.edn b/version.edn index a358a7e..98886d3 100644 --- a/version.edn +++ b/version.edn @@ -1 +1 @@ -{:major 0, :minor 12, :release 82} \ No newline at end of file +{:major 0, :minor 12, :release 83} \ No newline at end of file From ea361db52354e762eacc96ff8be43d69913d4222 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Sun, 26 Jul 2026 15:29:14 +0200 Subject: [PATCH 4/5] 83 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a962d9..27f33ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ For breaking changes, check [here](#breaking-changes). [Babashka CLI](https://github.com/babashka/cli): turn Clojure functions into CLIs! -## Unreleased +## 0.12.83 - Populate `:msg` in the `:error-fn` data for `dispatch` command errors (`:no-match`, `:input-exhausted`), like option errors already carry it - zsh completion: classify an option without a `:desc` as an option. It was added as a value, which offered it where zsh hides described options From e1c9dda59ecea54f977cb7e4aafce1484246c1ea Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Sun, 26 Jul 2026 15:52:03 +0200 Subject: [PATCH 5/5] zsh completion: offer options without typing a dash first --- CHANGELOG.md | 4 ++++ src/babashka/cli.cljc | 6 ++++++ test/babashka/cli/completion_test.cljc | 10 +++++++++- test/resources/completion/completion.zsh | 3 +++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27f33ae..57567d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ For breaking changes, check [here](#breaking-changes). [Babashka CLI](https://github.com/babashka/cli): turn Clojure functions into CLIs! +## Unreleased + +- zsh completion: offer a command's options without typing a dash first, by opting the registered program names out of zsh's `prefix-needed` style + ## 0.12.83 - Populate `:msg` in the `:error-fn` data for `dispatch` command errors (`:no-match`, `:input-exhausted`), like option errors already carry it diff --git a/src/babashka/cli.cljc b/src/babashka/cli.cljc index 7cfd912..2768237 100644 --- a/src/babashka/cli.cljc +++ b/src/babashka/cli.cljc @@ -1659,6 +1659,9 @@ fn (str "_babashka_cli_complete_" (str/replace program-name #"[^a-zA-Z0-9_]+" "_")) names-sp (str/join " " names) names-csv (str/join "," names) + names-zstyle (str/join "\n" + (map #(str "zstyle ':completion:*:*:" % ":*:options' prefix-needed false") + names)) names-nu (str "[" (str/join " " (map #(str "\"" % "\"") names)) "]")] (case shell :bash (str fn "() @@ -1743,6 +1746,9 @@ complete -F " fn " " names-sp " [[ -n $do_files ]] && { _files; ret=0; } return $ret } +# zsh hides options until a dash is typed. After a command there is usually +# nothing else to complete, so opt out for these programs only +" names-zstyle " # register the bare name(s); zsh's _normal completes ./name and /abs/name via the basename compdef " fn " " names-sp " ") diff --git a/test/babashka/cli/completion_test.cljc b/test/babashka/cli/completion_test.cljc index 4fb12d2..288f543 100644 --- a/test/babashka/cli/completion_test.cljc +++ b/test/babashka/cli/completion_test.cljc @@ -167,7 +167,15 @@ (is (not (str/includes? zsh "elif [[ $v == -* ]]")))) (testing "an option without a description is added under the options tag" (is (str/includes? zsh "bareopt+=(\"$v\")")) - (is (str/includes? zsh "_describe -t options option bareopt"))))) + (is (str/includes? zsh "_describe -t options option bareopt"))) + (testing "options are offered without typing a dash first" + (is (str/includes? zsh "zstyle ':completion:*:*:myprogram:*:options' prefix-needed false"))))) + +(deftest zsh-snippet-prefix-needed-per-name-test + (testing "every registered name opts out of prefix-needed" + (let [zsh (snippet-via-cmd cmd-table {:prog "x"} "zsh" "--prog" "sq" "--prog" "squint")] + (is (str/includes? zsh "zstyle ':completion:*:*:sq:*:options' prefix-needed false")) + (is (str/includes? zsh "zstyle ':completion:*:*:squint:*:options' prefix-needed false"))))) (defn- complete-out "Run the completion handler for `cmdline` and return its emitted diff --git a/test/resources/completion/completion.zsh b/test/resources/completion/completion.zsh index b9f8f3c..e8c8bb2 100644 --- a/test/resources/completion/completion.zsh +++ b/test/resources/completion/completion.zsh @@ -32,5 +32,8 @@ _babashka_cli_complete_myprogram() { [[ -n $do_files ]] && { _files; ret=0; } return $ret } +# zsh hides options until a dash is typed. After a command there is usually +# nothing else to complete, so opt out for these programs only +zstyle ':completion:*:*:myprogram:*:options' prefix-needed false # register the bare name(s); zsh's _normal completes ./name and /abs/name via the basename compdef _babashka_cli_complete_myprogram myprogram