19

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

我正在尝试为我的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 处于活动状态时调用

4

2 回答 2

4

我终于找到了解决这个问题的方法。虽然我对该策略不满意,因为它不是自包含在小部件本身中,但它确实有效。该解决方案涉及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
}

_takenote部件:

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

ps:我还是很想在小部件内移动陷阱,并避免在初始化脚本中注册它(.zshrc

于 2018-05-04T05:16:46.283 回答
1

尝试使用bindkey小部件使用 vim 打开fzf所选文件时,我遇到了同样的错误。原来我必须打开文件,function1然后有一个function2调用函数1,然后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

于 2020-04-29T04:20:18.367 回答