Виджеты могут вызываться только при активной ZLE
Я занимаюсь этой проблемой уже почти месяц, и я расстроен, любая помощь будет принята с благодарностью.
Я пытаюсь написать виджет для моего 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
3 ответа
Я наконец нашел решение этой проблемы. Хотя я не удовлетворен стратегией, поскольку она не содержится в самом виджете, но она работает. Решение включает в себя ловушку 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
)
Я получал ту же ошибку при попытке использовать 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
Через два дня мне наконец удалось найти подсказку, как этого добиться благодаря отличному проекту fzf-tab-completion:
Итак, на самом деле все, что вам нужно сделать, это:
#compdef takenote
local file=$( find -L "$HOME/notes/" -print 2> /dev/null | fzf-tmux +m )
compadd $file
TRAPEXIT() {
zle reset-prompt
}
return 0
И это, наконец, работает. Ваше здоровье!