我从很久以前(90 年代末或 00 年代初)就一直在使用 zsh compctl,但奇怪的是以前从未遇到过这种情况。今天我意识到,当我打算进行一些 compctl 配置时,update-alternatives
我的完成根本没有触发,它只是使用了我的标准后备完成(文件)... 因此,一个非常精简的简单示例来展示问题:
这很好用:
zshprompt% compctl -k '(arg1 arg2 arg3)' nodash
# typing 'nodash ' and hitting [Tab] once:
zshprompt% nodash arg
# hitting [Tab again]
zshprompt% nodash arg
arg1 arg2 arg3
但是这个完整的文件却是:
# just showing the current dir for reference:
zshprompt% ls .
file2.txt myfile1.txt
zshprompt% compctl -k '(arg1 arg2 arg3)' with-dash
# typing 'with-dash ' and hitting [Tab] once:
zshprompt% with-dash
file2.txt myfile1.txt
如图所示,使用了标准补全(列出当前目录),而不是我使用 compctl 添加的补全...
我在手册页(man zshcompctl)或网上确实找不到任何关于此内容的信息...所以,有人知道如何获取名称中带有破折号的 compctl 匹配命令吗?
短暂性脑缺血发作
答案1
已确认[电子邮件保护]邮件列表说这是一个错误,并得到了建议的补丁:
--- zsh-5.9.orig/Src/Zle/zle_tricky.c
+++ zsh-5.9/Src/Zle/zle_tricky.c
@@ -1315,6 +1315,8 @@ get_comp_string(void)
ins = (tok == REPEAT ? 2 : (tok != STRING && tok != TYPESET));
zsfree(cmdstr);
cmdstr = ztrdup(tokstr);
+ untokenize(cmdstr);
+ remnulargs(cmdstr);
cmdtok = tok;
/*
* If everything before is a redirection, or anything
我已经通过将更改作为 quilt 补丁应用到重建并安装的 Debian zsh_5.9-4 源包中进行了测试......并且它解决了我的问题。
我现在会继续运行它,如果它似乎没有破坏任何其他东西,我会确保它在 zsh 上游应用,期望它最终能够推广到所有不同的发行版。
如果您现在遇到问题,并且迫不及待地希望它在您的发行版中得到解决,请下载 zsh 5.9.4 源代码并使用上述补丁对其进行修补,然后在本地构建它。如果您希望将其集成到您的发行包中,以下是针对 Debian 的操作方法(应该适用于大多数基于 deb 包的发行版):
sudo apt install devscripts libcap-dev libelf-dev libgdbm-dev cm-super-minimal texinfo yodl quilt
mkdir /tmp/zsh_5.9
cd /tmp/zsh_5.9
apt source zsh=5.9-4
/bin/echo -e "1317a1318,1319\n> \t untokenize(cmdstr);\n> \t remnulargs(cmdstr);" > compctl-dash.diff
cd zsh-5.9
export QUILT_PATCHES=debian/patches
export QUILT_REFRESH_ARGS="-p ab --no-timestamps --no-index"
quilt push -a
quilt new compctl-dash.diff
quilt add Src/Zle/zle_tricky.c
patch Src/Zle/zle_tricky.c ../compctl-dash.diff
quilt refresh
quilt pop -a
debuild -b -uc -us
sudo dpkg -i ../zsh_5.9-4_amd64.deb
希望这个问题能被上游修复,并在下次更新软件包之前到达你的发行版,否则你将不得不重复此操作(或锁定 zsh 软件包版本)直到它完成 :-)