我有自定义脚本的 zsh 完成文件foo
。
它应该在以下位置完成常规文件$HOME/foo
:
#compdef foo
_arguments -S : \
'-i' \
'1:thing:_path_files -W $HOME/foo -g "*(.)"'
我需要修改完成如下:
添加可选参数--dir
。
当我输入时foo --dir<TAB>
,它应该提供目录的补全$HOME/foo
foo --dir=<TAB>
此外,文件完成路径($HOME/foo
默认情况下)应更改为$HOME/foo/my_dir
,其中my_dir
提供的名称为--dir=my_dir
。
更新:
基本上,完成规则应该有两种操作模式:
- 当我输入时
foo -<TAB>
,它应该为我提供可选参数(-d
-w
-l
-i
)。然后,根据选择的可选参数:
1a)foo -d <TAB>
仅完成路径中的目录
1b)foo -w / -l / -i <TAB>
完成路径中的常规文件
这按预期工作。
- 当我输入 时
foo <TAB>
,完成规则应该在路径中提供常规文件。目前,这并不能按预期工作。它仍然为我提供了可选参数,我必须选择一个参数,然后才能完成目录/文件。
当我输入foo <TAB>
(不带-
)时,它只为我提供选项参数。仅当我选择了可选参数之一后,我的完成规则才会在路径中提供目录/文件。
如何修复我的脚本,使其在没有任何可选参数的情况下工作,并且在这种情况下只需完成路径中的常规文件?
这是完成规则:
#compdef foo
local -A opt_args
_arguments -S -C \
'-i[select file]:thing_file:_path_files -W $HOME/manuals/${opt_args[-d]} -g "*(.)"' \
'-l[select file]:thing_file:_path_files -W $HOME/manuals/${opt_args[-d]} -g "*(.)"' \
'-w[select file]:thing_file:_path_files -W $HOME/manuals/${opt_args[-d]} -g "*(.)"' \
'-d[select directory]:directory_file:_path_files -/ -W $HOME/manuals' \
&& return 0
还有最后一个小问题。完成规则仅期望(完成)一个可选参数。
当我输入时,foo -i -<TAB>
它不提供其他剩余的可选参数。这些参数不应相互排斥。应该可以使用:
foo -i -l -w <TAB>
答案1
像那样:
#compdef foo
local -A opt_args
_arguments -S -C \
'-i[select file]:thing_file:_path_files -W $HOME/foo/${opt_args[-d]} -g "*(.)"' \
'-d[select directory]:directory_file:_path_files -/ -W $HOME/foo' \
&& return 0
解释它的功能如何工作:
创建~/foo:
mkdir ~/foo
在 ~/foo 中创建 10 个目录:
mkdir ~/foo/DIR{1..10}
在4号目录下创建一个文件:
$ touch ~/foo/DIR4/FILE4
以及 ~/foo 中的一个文件:
touch ~/foo/FILE-IN-FOO
类型
食物
并按Tab。表明:
$foo -d DIR1/
DIR1/ DIR10/ DIR2/ DIR3/ DIR4/ DIR5/ DIR6/ DIR7/ DIR8/ DIR9/
仅显示目录,因此没有 FILE-IN-FOO。
选择DIR4并添加-i:
foo -d DIR4 -i
并按Tab。表明:
foo -d DIR4 -i FILE4