我已经处理了这个问题差不多一个月了,我感到很沮丧,任何帮助都会非常感激。
我正在尝试为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
不幸的是,上面的代码由于zle reset-prompt
而无法正常工作,如果我将其删除,那么结果将是这样的:
选择文件后,它会变成:
如您所见,将破坏提示和命令本身。
在我看来,我需要做的是做zle reset-prompt
在调用compadd
之前,这只能在我将函数绑定到键时才能工作,否则会出现以下错误:
小部件只能在ZLE处于活动状态时调用
答案 0 :(得分:2)
我终于找到了解决这个问题的方法。虽然我对策略不满意,因为它不是自包含在小部件本身,但它的工作原理。该解决方案涉及在调用fzf-completion
后调用zle reset-prompt
并调用.zshrc
。
要注册陷阱,请将以下代码段添加到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
}
文件中(请参阅Zsh menu completion causes problems after zle reset-prompt
):
_takenote
#compdef takenote
local file=$( find -L "$HOME/notes/" -print 2> /dev/null | fzf-tmux +m )
compadd $file
return 0
小部件:
.zshrc
p.s:我仍然希望在窗口小部件中移动陷阱,并避免在init脚本中注册它(x = 10
)
答案 1 :(得分:0)
尝试将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