|
1 | 1 | (ns lambdaisland.cli.completions |
2 | 2 | (:require |
| 3 | + [lambdaisland.cli.cmdspec :as cmdspec] |
3 | 4 | [clojure.java.io :as io] |
4 | 5 | [clojure.string :as str])) |
5 | 6 |
|
| 7 | +(declare with-completions) |
| 8 | + |
6 | 9 | (defn zsh-completions [cmdspec {:lambdaisland.cli/keys [argv] :as opts}] |
7 | 10 | (let [cmdspec (reduce |
8 | 11 | (fn [cmdspec arg] |
9 | | - (let [commands ((resolve 'lambdaisland.cli/prepare-cmdpairs) (:commands cmdspec))] |
| 12 | + (let [commands (cmdspec/prepare-cmdpairs (:commands (with-completions cmdspec)))] |
10 | 13 | (if-let [command-match (get (into {} commands) arg)] |
11 | 14 | (-> cmdspec |
12 | 15 | (dissoc :command :commands :middleware) |
13 | 16 | (merge command-match) |
14 | | - (assoc :flagmap (merge (:flagmap ((resolve 'lambdaisland.cli/to-cmdspec) cmdspec)) |
15 | | - (:flagmap ((resolve 'lambdaisland.cli/to-cmdspec) command-match))))) |
| 17 | + (assoc :flagmap (merge (:flagmap (cmdspec/to-cmdspec cmdspec)) |
| 18 | + (:flagmap (cmdspec/to-cmdspec command-match))))) |
16 | 19 | cmdspec))) |
17 | 20 | cmdspec |
18 | 21 | (butlast (next argv)))] |
19 | | - (doseq [[cmd {:keys [doc]}] ((resolve 'lambdaisland.cli/prepare-cmdpairs) (:commands cmdspec))] |
20 | | - (println (str cmd (when doc ":") doc))) |
| 22 | + (doseq [[cmd {:keys [doc]}] (cmdspec/prepare-cmdpairs (:commands cmdspec))] |
| 23 | + (println (str cmd (when doc ":") (first (str/split doc #"\R"))))) |
21 | 24 | (doseq [[flag {:keys [doc]}] (:flagmap cmdspec)] |
22 | 25 | (println (str flag ":" (or doc (str/replace flag #"^-+" ""))))))) |
23 | 26 |
|
|
32 | 35 | (println "e.g. bin/my_script __install_zsh_completions /full/path/to/bin/my_script") |
33 | 36 | (System/exit -1)) |
34 | 37 | (when-not (.exists cdir) (.mkdirs cdir)) |
| 38 | + (println "Creating" (str (io/file cdir "_licli"))) |
35 | 39 | (spit (io/file cdir "_licli") |
36 | 40 | (slurp (io/resource "lambdaisland/cli/_licli.zsh"))) |
37 | 41 | ;; we could get a lot fancier here with detecting the block we previously |
38 | 42 | ;; added, but this is an ok start |
39 | | - (spit zshrc-path |
40 | | - (str zshrc |
41 | | - "\n" |
42 | | - (when-not (re-find #"(?m)^fpath=.*\~/.zsh/completions" zshrc) |
43 | | - (str "\n# lambdaisland.cli completions\nfpath=(~/.zsh/completions $fpath)\n")) |
44 | | - (when-not (re-find #"(?m)^autoload -Uz compinit$" zshrc) |
45 | | - (str "autoload -Uz compinit\n")) |
46 | | - (when-not (re-find #"(?m)^compinit$" zshrc) |
47 | | - (str "compinit\n")) |
48 | | - (let [base-name (last (str/split script-name #"/"))] |
49 | | - (str "compdef _licli " script-name " */" base-name " " base-name)))))) |
| 43 | + (let [stanza (str |
| 44 | + (when-not (re-find #"(?m)^fpath=.*\~/.zsh/completions" zshrc) |
| 45 | + (str "\n# lambdaisland.cli completions\nfpath=(~/.zsh/completions $fpath)\n")) |
| 46 | + (when-not (re-find #"(?m)^autoload -Uz compinit$" zshrc) |
| 47 | + (str "autoload -Uz compinit\n")) |
| 48 | + (when-not (re-find #"(?m)^compinit$" zshrc) |
| 49 | + (str "compinit\n")) |
| 50 | + (let [base-name (last (str/split script-name #"/"))] |
| 51 | + (str "compdef _licli " script-name " */" base-name " " base-name)))] |
| 52 | + (println "Updating" (str zshrc-path) ", adding:") |
| 53 | + (println stanza) |
| 54 | + (spit zshrc-path (str zshrc "\n" stanza))))) |
| 55 | + |
| 56 | +(defn install-bash-completions [opts] |
| 57 | + (throw (ex-info {} "Not implemented")) |
| 58 | + ) |
| 59 | + |
| 60 | +(defn install-completions |
| 61 | + "Do the necessary setup to get shell completions. Shell will be guessed from |
| 62 | + $SHELL, unless explicitly specified." |
| 63 | + {:flags ["--zsh" "Do zsh setup" |
| 64 | + "--bash" "Do bash setup"]} |
| 65 | + [opts] |
| 66 | + (let [shell (cond |
| 67 | + (:zsh opts) :zsh |
| 68 | + (:bash opts) :bash |
| 69 | + :else (keyword (last (str/split (System/getenv "SHELL") #"/"))))] |
| 70 | + (case shell |
| 71 | + :zsh (install-zsh-completions opts) |
| 72 | + :bash (install-bash-completions opts)))) |
50 | 73 |
|
51 | 74 | (defn with-completions [cmdspec] |
52 | 75 | (update cmdspec |
53 | 76 | :commands |
54 | 77 | (fnil into []) |
55 | | - ["__zsh_completions" {:no-doc true |
56 | | - :command (partial zsh-completions cmdspec)} |
57 | | - "__install_zsh_completions" {:no-doc true |
58 | | - :command #'install-zsh-completions}])) |
| 78 | + ["__licli" |
| 79 | + {:no-doc true |
| 80 | + :commands |
| 81 | + ["completions" {:doc "Generate completions based on partially completed arguments |
| 82 | +
|
| 83 | +called by shell functions to do the actual completing." |
| 84 | + :command (partial zsh-completions cmdspec)} |
| 85 | + "install-completions" #'install-completions]}])) |
0 commit comments