【问题标题】:widgets can only be called when ZLE is active小部件只能在 ZLE 处于活动状态时调用
【发布时间】:2018-01-02 04:30:18
【问题描述】:

我已经处理这个问题将近一个月了,我感到很沮丧,非常感谢任何帮助。

我正在尝试为我的takenote 命令编写一个小部件。小部件的目的是将~/notes 文件夹中的所有降价文件提供给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

很遗憾,上面的代码因为zle reset-prompt而不起作用,如果我删除它,结果会是这样的:

选择文件后会变成:

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

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

【问题讨论】:

  • 到目前为止运气好吗?如果您管理得当,我会使用该解决方案。
  • 不,抱歉!已经很久了,我没有找到解决办法。不过我真的很想知道答案。也许你可以投票赞成这个问题?
  • @animaacija,我试过试一试,但似乎需要更多的努力。我可以给你一个可能会有所帮助的指针。这是为vim 完成的,您可以根据自己的情况进行调整。见github.com/junegunn/fzf/issues/227
  • @ExistMe,连续第三次赏金 :-)。你有机会看看我发布的链接吗
  • @tarun-lalwani 谢谢,我花了一天时间在你建议的链接上,但没有成功:) 它有多复杂,我觉得我对 zle 和它的状态一无所知。我想说这主要是一个zle widget 问题而不是fzf

标签: widget zsh completion zsh-zle fzf


【解决方案1】:

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

要注册陷阱,请将以下 sn-p 添加到您的 .zshrc 文件中(请参阅 Zsh menu completion causes problems after 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
}

_takenote 小部件:

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

p.s:我仍然希望在小部件内移动陷阱,并避免在初始化脚本中注册它 (.zshrc)

【讨论】:

    【解决方案2】:

    我在尝试使用 bindkey 小部件以使用 vim 打开 fzf 选定文件时遇到同样的错误。原来我必须在function1 中打开文件,然后有一个function2 调用function1,然后reset-prompt 以避免这个widgets can only be called when ZLE is active 错误。就像你说的,这真的是令人沮丧,我花了将近一天的时间才弄明白!

    示例代码:

    ## use rg to get file list
    export FZF_DEFAULT_COMMAND='rg --files --hidden'
    
    ## file open (function1)
    __my-fo() (
      setopt localoptions pipefail no_aliases 2> /dev/null
      local file=$(eval "${FZF_DEFAULT_COMMAND}" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS --preview 'bat --color=always --line-range :500 {}'" $(__fzfcmd) -m "$@" | while read item; do
        echo -n "${(q)item}"
      done)
      local ret=$?
      if [[ -n $file ]]; then
        $EDITOR $file
      fi
      return $ret
    )
    
    ## define zsh widget(function2)
    __my-fo-widget(){
      __my-fo
      local ret=$?
      zle reset-prompt
      return $ret
    }
    
    zle -N __my-fo-widget
    bindkey ^p __my-fo-widget
    
    

    【讨论】:

    • 这个问题现在已经很老了,我仍然对更好的解决方案感兴趣。据我记得,当使用bindkey 绑定到组合键时,zle reset-prompt 足以完成这项工作。真正的痛苦是当您想要使用选项卡完成时。除了TRAPALRM 方法,我找不到任何替代方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-27
    • 2020-07-04
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多