我使用zsh
及其 Tab 补全功能。当我在(慢速)NFS 目录中意外按下 Tab 键时,zsh
会花费太长时间。更糟糕的是,如果 NFS 已关闭,而我按下/mnt/[tab]
,我的整个 shell 都会被锁定。
如何禁用zsh
这些目录中的制表符补全?
答案1
如果您在这些目录中,要完全禁用完成功能,您可以使用以下代码:
function restricted-expand-or-complete() {
if [[ ! $PWD = /mnt/* ]]; then
zle expand-or-complete
else
echo -en "\007"
fi
}
zle -N restricted-expand-or-complete
bindkey "^I" restricted-expand-or-complete
这定义了一个函数,用于检查您的工作目录是否以 开头/mnt/
。如果不是,则通过 调用默认完成函数,zle expand-or-complete
否则会发出哔声。该函数被声明为小部件 ( zle -N
) 并绑定到TAB( bindkey
)。
然而,这只是一个开始,因为当你做这样的事情时
/foo/bar$ cp hello.c /mnt/[TAB]
你又迷路了。所以你还必须将/mnt/
树从完成系统中排除。根据文档,这应该可以解决问题:
zstyle ':completion:*:*files' ignored-patterns '/mnt/*'
zstyle ':completion:*:*directories' ignored-patterns '/mnt/*'
但我不确定这是否会阻止任何 stat 函数调用/mnt/
或仅在之后删除匹配项。请尝试,如果仍然有明显的延迟,请将函数中的 if 子句扩展restricted-expand-or-complete
为
if [[ ! $PWD = /mnt/* && ! ${${(z)LBUFFER}[-1]} = */mnt/* ]]
[编辑]
我重新设计了这个 hack,让它更加灵活,但它仍然存在问题,我仍然确信直接修改完成函数(也许_path_files
)会更简洁。然而...
这是有效的(示例中的摘要):
ls <TAB>
被阻塞在慢速目录中 (/mnt
)ls /mnt/<TAB>
被阻止ls /home/user/symlink_to_mnt/<TAB>
被阻止cd /; ls mnt/<TAB>
被阻止tar --exclude-from=/mnt/<TAB>
被阻止(其他变体、符号链接、相对路径也是如此)
这不起作用:
- 路径内完成仍然
/m/s/p
完成/mnt/some/path
- 如果选项不以 开头
-
,则命令选项的完成将被阻止,例如apt-get inst<TAB>
在 /mnt 中不起作用 - 在
/
Cygwin 下出现奇怪的行为,而在 Linux 下一切正常
代码如下:
function restricted-expand-or-complete() {
# split into shell words also at "=", if IFS is unset use the default (blank, \t, \n, \0)
local IFS="${IFS:- \n\t\0}="
# this word is completed
local complt
# if the cursor is following a blank, you are completing in CWD
# the condition would be much nicer, if it's based on IFS
if [[ $LBUFFER[-1] = " " || $LBUFFER[-1] = "=" ]]; then
complt="$PWD"
else
# otherwise take the last word of LBUFFER
complt=${${=LBUFFER}[-1]}
fi
# determine the physical path, if $complt is not an option (i.e. beginning with "-")
[[ $complt[1] = "-" ]] || complt=${complt:A}/
# activate completion only if the file is on a local filesystem, otherwise produce a beep
if [[ ! $complt = /mnt/* && ! $complt = /another/nfs-mount/* ]]; then
zle expand-or-complete
else
echo -en "\007"
fi
}
zle -N restricted-expand-or-complete
bindkey "^I" restricted-expand-or-complete