基于多个路径的自定义 zsh 完成 [英] custom zsh completion based on multiple paths

查看:30
本文介绍了基于多个路径的自定义 zsh 完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为接受目录作为参数的命令编写自定义完成.我认为用一个例子来解释它应该如何工作是最容易的.

I want to write a custom completion for a command that accepts a directory as an argument. I think it's easiest to explain how it is supposed to work with an example.

假设我在某处定义了一个目录列表:

Let's assume I have a list of directories defined somewhere:

d=(~/somedir/foo ~/somedir/foo/bar ~/other/dir/baz)

对命令的有效调用是

mycmd foo
mycmd bar
mycmd baz
mycmd baz/and/some/subdir

完成后应该可以做

mycmd f<TAB>              => mycmd foo
mycmd baz/and/some/s<TAB> => mycmd baz/and/some/subdir

不知何故,我对 zshcompsys 的复杂性有点迷茫,所以我不确定如何最好地实现这一点.

Somehow I'm a bit lost in the complexity of zshcompsys, so I'm not really sure how to approach this best.

推荐答案

1.预定义的目录作为参数.

如果你事先知道 mycmd 的参数可以是什么,你可以使用一个非常简单的完成函数,里面的值是硬编码的:

1. Pre-defined directories as arguments.

If you know in advance what the arguments of mycmd can be, you can just use a very simple completion function with the values hard-coded inside:

 #compdef _mycmd
 _arguments "1: :(foo bar baz baz/and/some/subdir)"

这给出了以下内容:

zsh% mycmd<TAB>
bar                    baz                    baz/some/other/subdir  foo    
zsh% mycmd baz<TAB>
baz                    baz/some/other/subdir
zsh% mycmd baz/<TAB>
zsh% mycmd baz/some/other/subdir 

2.完成一个目录内的所有子目录

假设 foo 的任何子目录都是 mycmd 的有效路径:

2. Completion to all subdirectories within a directory

Assuming that any subdirectory of foo is a valid path for mycmd:

~/foo/bar         # Valid path
~/foo/subdir/baz  # Valid path
~/baz/bar         # Invalid path

你可以告诉 compctl 完成 foo 内的任何目录作为 mycmd 的参数:

you can tell compctl to complete any directory within foo as an argument to mycmd:

# In your ~/.zshrc
compctl -/ -W ~/foo mycmd

我不知道这与您编写的 mycmd 的任何其他完成函数的效果如何(例如,如果 mycmd 也采用非文件名参数).它是这样完成的:

I do not know how well this will play with any other completion function for mycmd that you have written (for example, if mycmd also takes non-filename arguments). It completes like this:

zsh% mycmd<TAB>
bar/  baz/  caz/
zsh% mycmd baz/s<TAB>
zsh% mycmd baz/subdir/

注意:我的路径/命令有点长.我在下面的粘贴中剪掉了一些(替换为 ...).

3.使用预定义的数组.

如果我们有一个数组 d=(foo bar baz),其中每个元素都是 mycmd 的有效补全,我们可以使用 -k:

Note: my paths / commands got a bit long. I've snipped some in the below pastes (replaced with ...).

3. Using pre-defined arrays.

If we have an array d=(foo bar baz), where each element is a valid completion for mycmd, we can use -k:

→ compctl -k "(foo bar baz)" mycmd
→ mycmd
bar  baz  foo

4.数组的子目录.

使用以下目录结构:

4. Subdirectories of arrays.

Using the following directory structure:

~/.../somedir
~/.../somedir/bar
~/.../somedir/foo
~/.../somedir/foo/invalid
~/.../otherdir
~/.../otherdir/subdir
~/.../otherdir/subdir/baz

compctl-W 选项也接受一个数组作为参数,允许这样做:

The -W option of compctl also takes an array as an argument, allowing this:

→ compctl -/ -W "(/.../otherdir /.../somedir)" mycmd
→ mycmd <TAB>
bar/     foo/     subdir/

我很确定这现在与您想要的相匹配.
注意: -W 选项与 -/ 一起使用(阅读 zshcompctl 的手册页)- -W 不能单独工作.

I'm fairly sure this now matches to what you want.
Note: The -W option works with the -/ (read the man page for zshcompctl) - -W doesn't work on it's own.

让我们假设有效的参数是:

Let's assume that valid arguments are:

mycmd foo  # Valid
mycmd baz  # Valid
mycmd baz/and/some/subdir # Valid - subdirectory of `baz`
mycmd foo/subdir # Invalid!! 

我们想要foo的子目录,只想要baz的子目录.我们可以通过混合 -k-/-W 来实现:

where we do not want subdirectories of foo, only of baz. We can achieve this by mixing -k and -/ -W:

→ compctl -/ -W "(/.../otherdir)" -k "(/.../somedir/foo)" mycmd
→ mycmd <TAB>
/Users/simont/sandbox/completion/somedir/foo  subdir/ 
→ mycmd foo/<TAB> # No further completion - we can't complete foo/invalid. 
→ mycmd subdir/<TAB>
→ mycmd subdir/baz/

然而,这会留下 foo 的完整路径(与 -W 不同,它删除了它).要解决此问题,请不要将其放入 -k 的数组中:

This, however, leaves the full path to foo (unlike -W, which removes it). To fix this, don't put it into the array for -k:

compctl -/ -W "(/.../otherdir)" -k "(foo)" mycmd

这篇关于基于多个路径的自定义 zsh 完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆