我想知道如何配置嘚到不是扩展文件名中的通配符。例如,我有一个包含数百个文件的目录,其名称如下:
a.foo-bar a.foo b.foo-bar b.foo c.foo-bar c.foo
我希望能够执行制表符补全匹配后通配符,因此
cat *.foo-< tab > => cat *.foo-bar
这是我得到的:
$ cat *.foo- => 猫 a.foo-bar 文件 a.foo-bar b.foo-bar c.foo-bar
答案1
一个选项是,你可以用默认的键绑定替换TAB
键
bindkey "^I" expand-or-complete
和
bindkey "^I" complete-word
它不会将 a 扩展*
到所有匹配的文件,但不会改变星号。这样,您就摆脱了无尽的列表,但它仍然无法完成通配符表达式。
解决这个问题要棘手得多。你必须自己写完成小部件(看man zshcompwid
)。
让我们从定义开始:
zle -C complete-glob menu-complete compglob
这引入了新的小部件完整全局,其行为类似于菜单完成并使用shell 函数 康普环球来生成匹配。
[ 注意:如果你不想使用菜单完成功能,请使用更基本的选项完整单词或者列表选项]
将这个新的小部件绑定到一个方便的快捷方式,例如
CTRL+K
:bindkey "^K" complete-glob
不要将其绑定到
TAB
,因为其当前形式的小部件仅完成文件!定义 shell 函数康普环球如下所示,它完成实际的工作:
compglob () { setopt localoptions globsubst compset -P '*' files=(${IPREFIX}*) display=(${files/${IPREFIX}/${(q)IPREFIX}}) glob=(${files/${IPREFIX}/}) compadd -d display -- $glob }
示范:
$ touch a.foo-bar a.foo b.foo-bar b.foo c.foo-bar c.foo $ cat *.f<CTRL+K> $ cat *.foo \*.foo \*.foo-bar
我看到的唯一缺陷是
\
所列列表中星星前面的 。但这只是一个视觉缺陷,因为完成是正确的:*.foo
或*.foo-bar
。
答案2
我认为这是不可能的。您不仅要求 shell 找出您希望和不希望哪些文件最终“根据通配符扩展有效”,还希望 shell 找出以这种方式扩展的“最佳”通配符表达式。我希望第二部分是 NP 完全的。
答案3
我目前还没有找到一种方法可以让你得到你想要的东西,但你可以通过setopt GLOB_COMPLETE
(这将只给你一个扩展,然后你可以通过它们进行选项卡浏览...或者只编辑那个,使其再次成为*
,这至少是一个小小的改进)进行一些修改(这可能对你有帮助,也可能没用)。
man zshoptions
您也可以在、man zshcompctl
和/或类似内容中挖掘man zshcompwid
。zsh 的完成内容相当复杂,所以我猜可能有办法做到这一点。
另请注意,一个有点相关的问题: