Skip to content

Instantly share code, notes, and snippets.

@jeroenvandijk
Created April 29, 2021 20:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jeroenvandijk/42a570415a45c68989f4f506977050c4 to your computer and use it in GitHub Desktop.
Save jeroenvandijk/42a570415a45c68989f4f506977050c4 to your computer and use it in GitHub Desktop.
babashka autocomplete (semi-working) idea
#!/usr/bin/env bash
;; From https://github.com/remkop/picocli/blob/master/src/test/resources/picocompletion-demo-help_completion.bash#L45
;; Copy following in terminal (bash / zsh)
;
; if [ -n "$BASH_VERSION" ]; then
; # Enable programmable completion facilities when using bash (see [3])
; shopt -s progcomp
; elif [ -n "$ZSH_VERSION" ]; then
; # Make alias a distinct command for completion purposes when using zsh (see [4])
; setopt COMPLETE_ALIASES
; alias compopt=complete
;
; # Enable bash completion in zsh (see [7])
; autoload -U +X compinit && compinit
; autoload -U +X bashcompinit && bashcompinit
; fi
;
; complete -C "bb $PWD/complete.bb" -o default bb-complete
(require '[babashka.tasks :refer [shell]])
;; Following could be generated based on tasks in bb.edn or could be part of it
(def tree
'{:opts #{--a --c}
:cmds {aa {:cmd (println "a")
:opts #{--foo}}
aaa {:cmd (println "a")
:opts #{--foo}}
bb {:opts #{--bar}
:cmds
{sub1
{:opts #{a}}}}
}})
(if-let [args (or (some-> (System/getenv "COMP_LINE")
(clojure.string/split #" ")
rest) ;; FIXME Poor man cmd parsing here
(and (= (first *command-line-args*) "--autocomplete")
(rest *command-line-args*)))]
(do
(loop [[arg & left-args] (map symbol args)
branch (:cmds tree)
left-opts (:opts tree)]
(or (and left-args
(do
(if-let [next-branch (get branch arg)]
(recur left-args (:cmds next-branch) (:opts next-branch))
(if (get left-opts arg)
(recur left-args branch (disj left-opts arg))
nil ;; cannot autocomplete
)
)))
;; No need to look further present all options and leave it to complete
(let [arg (str arg)
current-opts (-> (into #{} (map str (concat (keys branch) left-opts)))
(disj arg))]
(println (clojure.string/join "\n" current-opts))))))
(println "Normal execution"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment