当完成函数需要很长时间时,我可以打断它通过按Ctrl+ C(终端中断键,发送SIGINT)或Ctrl+ G(绑定到send-break
)。然后我就留下了未完成的单词。
但是,如果我碰巧在完成功能完成时按下Ctrl+C或Ctrl+ G,我的按键可能会取消命令行并给我一个新的提示,而不是取消完成。
如何设置 zsh 以便某个键取消正在进行的完成,但如果没有激活完成功能则不执行任何操作?
答案1
这是一个设置 SIGINT 处理程序的解决方案,该处理程序仅在完成处于活动状态时才中断 Ctrl+ 。C
# A completer widget that sets a flag for the duration of
# the completion so the SIGINT handler knows whether completion
# is active. It would be better if we could check some internal
# zsh parameter to determine if completion is running, but as
# far as I'm aware that isn't possible.
function interruptible-expand-or-complete {
COMPLETION_ACTIVE=1
# Bonus feature: automatically interrupt completion
# after a three second timeout.
# ( sleep 3; kill -INT $$ ) &!
zle expand-or-complete
COMPLETION_ACTIVE=0
}
# Bind our completer widget to tab.
zle -N interruptible-expand-or-complete
bindkey '^I' interruptible-expand-or-complete
# Interrupt only if completion is active.
function TRAPINT {
if [[ $COMPLETION_ACTIVE == 1 ]]; then
COMPLETION_ACTIVE=0
zle -M "Completion canceled."
# Returning non-zero tells zsh to handle SIGINT,
# which will interrupt the completion function.
return 1
else
# Returning zero tells zsh that we handled SIGINT;
# don't interrupt whatever is currently running.
return 0
fi
}
答案2
我不知道这是否是一个可接受的解决方案,但发送 SIGSTOP ( Ctrl+ ) 似乎具有预期的效果,还有一个额外的好处,如果您在输入之前发送 SIGSTART ( + ) S,则可以再次启动自动完成功能还要别的吗。不过,我不是作业控制方面的专家,因此这可能会留下一些与停止作业相关的额外混乱。CtrlQ