-
Notifications
You must be signed in to change notification settings - Fork 25
Zsh completion for cligen commands (with colored help output)
Zsh includes a large selection of parsers to support auto completion for a variety of commands. Common GNU tools with a 'standardized' -h/--help
interface normally use the _gnu_generic
completion module.
Unfortunately, when cligen
's help output includes ANSI SGR color escape sequences, it breaks _gnu_generic
's --help parser. At least as of Zsh version 5.9 this can be easily worked around by disabling the cligen
color escape sequences in the context of the help parsing with something like this in your ~/.zshrc
(or $ZDOTDIR/.zshrc
):
compinit -u # probably already in your .zshrc
_ggnc() { NO_COLOR=1 _gnu_generic; } # define _gnu_generic_no_color completer
## list of completers to use, extend by custom `_ggnc` completer
zstyle ':completion:*::::' completer _complete _ggnc # + others like _expand?
We make use of setting the NO_COLOR environment variable (supported by cligen
) to disable the color escape sequences only in the context of the _gnu_generic
call.
While the above works and is quick to describe, it applies _gnu_generic fairly promiscuously which can be dangerous since any-command --help
may not produce parsable output or even be safe to run. A more refined config would be a separate somewhere-in-FPATH file perhaps called _cligen
looking like:
#compdef cols dirq dirt dups fkindc newest only rp rr
NO_COLOR=1 _gnu_generic
With either setup & Zsh restarted, you should get a nice list of possible completions when typing dups -<TAB>
, with dups.nim
from examples/
:
dups -
--brief -b -- bool false do NOT print sets of dups
--cmp -c -- bool false compare; do not trust hash
--delim -d -- char 'n' input file delimiter; 0 -> NUL
--Deref -D -- bool false dereference symlinks
--endOut -e -- string "n" output record terminator
--file -f -- string "" optional input ( "-" | !tty = stdin )
--follow -F -- bool false follow symlinks to dirs in recursion
--Hash -H -- Digest wy hash function (size|wy|nim|SHA)
--jobs -j -- int 1 Use this much parallelism
--log -l -- set(Lg) osErr >stderr{ osErr, summ }
--minLen -m -- int 1 minimum file size to consider
--outDlm -o -- string "t" output internal delimiter
--recurse -r -- 1 recurse n-levels on dirs; 0- unlimited
--slice -s -- string "" file slice (float|%-frac; <0-tailRel)
--time -t -- string "" sort each set by file time- {-}(bamcv).*
--xdev -x -- bool false block cross-device recursion
Completion of individual options should work as expected, including filtering to remaining matching (e.g. for multiple options starting with --f*
typing --f<TAB>
only lists the remaining, in this case --file
& --follow
.
Arguably it would be better to upstream something to Zsh using the NO_COLOR
convention cligen
apps honor by default. Then if any other CLI toolkit/framework supports colorized --help
, it can honor the same convention and Zsh can just work. The bash complete -F _longopt
does not seem to require any of this, and shells do like to compete with each other. Color in terminals is also pretty popular. So, chances are high that a change like this would be accepted by Zsh maintainers, especially as a new name like _gnu_generic_no_color
, but possibly even more directly as setting NO_COLOR=1 ahead of _call_command. Let me know if you do that and these instructions may simplify to use Zsh version > X. :-)