I want to create a zsh completion for a tool with a virtual file tree. e.g. my file tree looks like the following:
/ |- foo/ | |- bar | |- baz/ | |- qux |- foobar My tool mycmd has a subcommand for listing the current directory:
$ mycmd ls foo/ foobar $ mycmd ls foo/ bar baz/ My actual zsh completion looks like this:
_mycmd_ls() { if [ ! -z "$words[-1]" ]; then dir=$(dirname /$words[-1]) lastpart=$(basename $words[-1]) items=$(mycmd ls $dir | grep "^$lastpart") else items=$(mycmd ls) fi _values -s ' ' 'items' ${(uozf)items} } _mycmd() { local -a commands commands=( 'ls:list items in directory' ) _arguments -C -s -S -n \ '(- 1 *)'{-v,--version}"[Show program\'s version number and exit]: :->full" \ '(- 1 *)'{-h,--help}'[Show help message and exit]: :->full' \ '1:cmd:->cmds' \ '*:: :->args' \ case "$state" in (cmds) _describe -t commands 'commands' commands ;; (args) _mycmd_ls ;; (*) ;; esac } _mycmd IMHO is _values the wrong utility function. The actual behaviour is:
$ mycmd ls<TAB> foo/ foobar $ mycmd ls foo/<TAB> ## <- it inserts automatically a space before <TAB> and so $words[-1] = "" foo/ foobar I can't use the utility function _files or _path_files because the file tree is only virtual.