|
2 | 2 | "Private namespace for implementation details for new.lewisship.cli-tools, subject to change." |
3 | 3 | (:require [clojure.string :as string] |
4 | 4 | [clj-commons.ansi :refer [compose pout perr]] |
| 5 | + [net.lewisship.cli-tools.styles :refer [style]] |
5 | 6 | [clojure.tools.cli :as cli] |
6 | 7 | [clj-commons.humanize :as h] |
7 | 8 | [clj-commons.humanize.inflect :as inflect] |
|
186 | 187 | "Usage: " |
187 | 188 | ;; A stand-alone tool doesn't have a tool-name (*options* will be nil) |
188 | 189 | (when tool-name |
189 | | - [:bold.green tool-name " "]) |
| 190 | + [(style :tool-name) tool-name " "]) |
190 | 191 | ;; A stand-alone tool will use its command-name, a command within |
191 | 192 | ;; a multi-command tool will have a command-path. |
192 | | - [:bold.green (if command-path |
193 | | - (string/join " " command-path) |
194 | | - command-name)] |
| 193 | + [(style :command-path) |
| 194 | + (if command-path |
| 195 | + (string/join " " command-path) |
| 196 | + command-name)] |
195 | 197 | " [OPTIONS]" |
196 | 198 | (map list (repeat " ") arg-strs)) |
197 | 199 | (when command-doc |
|
210 | 212 | lines (for [{:keys [label doc]} positional-specs] |
211 | 213 | (list |
212 | 214 | [{:width max-label-width} |
213 | | - [:bold label]] |
| 215 | + [(style :option-label) label]] |
214 | 216 | ": " |
215 | 217 | doc))] |
216 | 218 | (pout "\nArguments:") |
|
220 | 222 | [errors] |
221 | 223 | (let [{:keys [tool-name]} *tool-options*] |
222 | 224 | (perr |
223 | | - [:red |
| 225 | + [(style :parse-error) |
224 | 226 | (inflect/pluralize-noun (count errors) "Error") |
225 | 227 | (when tool-name |
226 | 228 | (list |
|
266 | 268 | (when default-fn "<computed>") |
267 | 269 | "") |
268 | 270 | "")] |
269 | | - {:opt-label [:bold opt-label] |
| 271 | + {:opt-label [(style :option-label) opt-label] |
270 | 272 | :opt-width (.length opt-label) |
271 | | - :default [:italic default-desc] |
| 273 | + :default [(style :option-default) default-desc] |
272 | 274 | :default-width (.length default-desc) |
273 | 275 | :opt-desc desc})) |
274 | 276 |
|
|
707 | 709 | (collect-subs command-root *result) |
708 | 710 | (-> *result deref persistent!))) |
709 | 711 |
|
710 | | -(def ^:private missing-doc [:yellow.italic "(missing documentation)"]) |
| 712 | +(defn- missing-doc |
| 713 | + [] |
| 714 | + [(style :missing-doc) "(missing documentation)"]) |
711 | 715 |
|
712 | 716 | (defn extract-command-title |
713 | 717 | [command-map] |
|
733 | 737 | (list |
734 | 738 | (h/numberword group-count) " " |
735 | 739 | (inflect/pluralize-noun group-count "sub-group")))])) |
736 | | - missing-doc)) |
| 740 | + (missing-doc))) |
737 | 741 |
|
738 | 742 | (defn- print-commands |
739 | 743 | [command-name-width container-map commands-map recurse?] |
|
747 | 751 | (reduce max 0)))] |
748 | 752 | (when container-map |
749 | 753 | (pout (when recurse? "\n") |
750 | | - [:bold (string/join " " (:command-path container-map))] |
| 754 | + [(style :command) (string/join " " (:command-path container-map))] |
751 | 755 | " - " |
752 | 756 | (or (some-> container-map :group-doc cleanup-docstring) |
753 | | - missing-doc))) |
| 757 | + (missing-doc)))) |
754 | 758 |
|
755 | 759 | (when (seq sorted-commands) |
756 | 760 | (pout "\nCommands:")) |
|
759 | 763 | (doseq [{:keys [fn command] :as command-map} sorted-commands] |
760 | 764 | (pout |
761 | 765 | " " |
762 | | - [{:width command-name-width'} [:bold.green command]] |
| 766 | + [{:width command-name-width'} [(style :command-path) command]] |
763 | 767 | ": " |
764 | | - [(when-not fn :italic) |
| 768 | + [(when-not fn (style :subgroup-label)) |
765 | 769 | (extract-command-title command-map)])) |
766 | 770 |
|
767 | 771 | ;; Recurse and print sub-groups |
|
781 | 785 | matching-commands (->> (filter #(command-match? % search-term') all-commands) |
782 | 786 | (map #(update % :command-path join-command-path)))] |
783 | 787 | (if-not (seq matching-commands) |
784 | | - (pout "No commands match " [:italic search-term']) |
| 788 | + (pout "No commands match " [(style :search-term) search-term']) |
785 | 789 | (let [command-width (->> matching-commands |
786 | 790 | (map :command-path) |
787 | 791 | (map count) |
|
792 | 796 | (if (= n 1) |
793 | 797 | " command matches " |
794 | 798 | " commands match ") |
795 | | - [:italic search-term'] |
| 799 | + [(style :search-term) search-term'] |
796 | 800 | ":" "\n") |
797 | 801 | (doseq [{:keys [command-path] :as command} (sort-by :command-path matching-commands)] |
798 | | - (pout [{:font :bold.green |
| 802 | + (pout [{:font (style :command-path) |
799 | 803 | :width command-width} |
800 | 804 | command-path] |
801 | 805 | ": " |
|
805 | 809 | [level] |
806 | 810 | (let [{tool-doc :doc |
807 | 811 | :keys [tool-name command-root]} *tool-options*] |
808 | | - (pout "Usage: " [:bold.green tool-name] " [OPTIONS] COMMAND ...") |
| 812 | + (pout "Usage: " [(style :tool-name) tool-name] " [OPTIONS] COMMAND ...") |
809 | 813 | (when tool-doc |
810 | 814 | (pout "\n" |
811 | 815 | (cleanup-docstring tool-doc))) |
|
841 | 845 | (sort (filter (to-matcher s) values'))))) |
842 | 846 |
|
843 | 847 | (def ^:private help |
844 | | - (list |
845 | | - [:bold.green "--help"] " (or " [:bold.green "-h"] ") to list commands")) |
| 848 | + (let [option-style (style :option-name)] |
| 849 | + (list |
| 850 | + [option-style "--help"] " (or " [option-style "-h"] ") to list commands"))) |
846 | 851 |
|
847 | 852 | (defn- use-help-message |
848 | 853 | [tool-name] |
849 | | - (list ", use " [:bold.green tool-name] " " help)) |
| 854 | + (list ", use " [(style :tool-name) tool-name] " " help)) |
850 | 855 |
|
851 | 856 | (defn- no-command |
852 | 857 | [tool-name] |
853 | | - (abort [:bold.green tool-name] ": no command provided" (use-help-message tool-name))) |
| 858 | + (abort [(style :tool-name) tool-name] ": no command provided" (use-help-message tool-name))) |
854 | 859 |
|
855 | 860 | (defn- incomplete |
856 | 861 | [tool-name command-path matchable-terms] |
857 | 862 | (abort |
858 | | - [:bold.green tool-name ": " |
| 863 | + [(style :tool-name) tool-name ": " |
859 | 864 | (string/join " " command-path)] |
860 | 865 | " is incomplete; " |
861 | 866 | (compose-list matchable-terms) |
|
877 | 882 | " " |
878 | 883 | help)] |
879 | 884 | (abort |
880 | | - [:bold [:green tool-name] ": " |
881 | | - [:green (string/join " " command-path)] |
| 885 | + [(style :no-command-match) |
| 886 | + [(style :tool-name) tool-name] ": " |
| 887 | + [(style :command-path) (string/join " " command-path)] |
882 | 888 | (when (seq command-path) " ") |
883 | | - [:red term]] |
| 889 | + [(style :unknown-term) term]] |
884 | 890 | " " |
885 | 891 | body |
886 | 892 | help-suffix))) |
|
0 commit comments