只有在ZLE处于活动状态时才能调用小部件

Exi*_*tMe 18 zsh widget completion fzf zsh-zle

我已经处理了这个问题差不多一个月了,我感到很沮丧,任何帮助都会非常感激.

我正在尝试为我的takenote命令编写一个小部件.小部件的目的是将文件~/notes夹中的所有markdown文件提供fzf给用户,以便用户可以选择其中一个并开始编辑它.在用户输入takenote并按下之后,<tab>我希望小部件能够运行.

这是_takenote.zsh小部件定义:

#compdef takenote
local file=$( find -L "$HOME/notes/" -print 2> /dev/null | fzf-tmux +m )
zle reset-prompt
compadd $file
return 1
Run Code Online (Sandbox Code Playgroud)

不幸的是,上面的代码不起作用,因为zle reset-prompt,如果我删除它然后结果将是这样的:

在选择之前

选择文件后,它将变成:

选择文件后

如您所见,将破坏提示和命令本身.在我看来,我需要做的是zle reset-prompt 在调用之前做一个compadd但这只有在我将函数绑定到一个键时才能工作,否则,我将得到以下错误:

只有在ZLE处于活动状态时才能调用小部件

Exi*_*tMe 6

我终于找到了解决该问题的方法。虽然我对该策略不满意,因为它不是独立包含在小部件本身中,但它确实有效。解决方案包括fzf-completion在调用它后进行捕获并调用zle reset-prompt.

要注册陷阱,请将以下代码片段添加到您的.zshrc文件中(请参阅Zsh 菜单完成在 zle reset-prompt 之后导致问题 ):

TMOUT=1
TRAPALRM() {
   if [[ "$WIDGET" =~ ^(complete-word|fzf-completion)$ ]]; then
      # limit the reset-prompt functionality to the `takenote` script
      if [[ "$LBUFFER" == "takenote "* ]]; then
         zle reset-prompt
      fi
   fi
}
Run Code Online (Sandbox Code Playgroud)

_takenote部件:

#compdef takenote
local file=$( find -L "$HOME/notes/" -print 2> /dev/null | fzf-tmux +m )
compadd $file
return 0
Run Code Online (Sandbox Code Playgroud)

ps:我仍然喜欢将陷阱移动到小部件内,并避免在初始化脚本中注册它(.zshrc


zrf*_*zrf 3

两天后,由于优秀的 fzf-tab-completion 项目,我终于找到了如何实现它的提示:

https://github.com/lincheney/fzf-tab-completion/blob/c91959d81320935ae88c090fedde8dcf1ca70a6f/zsh/fzf-zsh-completion.sh#L120

所以实际上,您需要做的就是:

#compdef takenote
local file=$( find -L "$HOME/notes/" -print 2> /dev/null | fzf-tmux +m )
compadd $file
    
TRAPEXIT() {
   zle reset-prompt
}
return 0
Run Code Online (Sandbox Code Playgroud)

它终于起作用了。干杯!