У меня есть функция автодополнения zsh для команды, gd
которая выполняет нечеткий поиск на основе $words[CURRENT]
значения и возвращает предложения. Поиск работает нормально, но zsh не показывает никаких кандидатов, потому что введенный текст не является префиксом предложения.
например
% gd hw
Может сгенерировать завершениеoh hello there, world
Но zsh этого не покажет, поскольку hw
не найден в начале предложения.
Могу ли я сделать так, чтобы zsh предлагал что-то, что заменит текущее слово при его выборе?
Вот упрощенная версия моего скрипта завершения в файле под названием , _gd
который находится в моем fpath
:
#compdef gd
_gd() {
local -a list
clue="$words[CURRENT]"
pattern=""
for i in $(seq $#clue)
do
pattern="$pattern.*${clue[i]}"
done
while read dir
do
list=( $list $dir )
done <<<$(grep "$pattern" ~/.recent-dirs)
_describe gd list
}
решение1
Избавьтесь от этой функции и просто добавьте в свой файл _gd
следующее :.zshrc
autoload -Uz compinit
compinit
zstyle ':completion:*' matcher-list 'r:|?=**'
Это говорит коду завершения разрешить любое количество дополнительных между и вокруг того, что вы набрали. С этим Zsh теперь может нечетко завершитьчто-либо.
r:X|Y=Z
ищет все неперекрывающиеся подстроки, которые соответствуют шаблонуXY
, и делает так, чтобы часть, совпавшая сX
такжесопоставляет все, что соответствует шаблону,Z
при проверке на совпадающие завершения.?
соответствует любому одному символу.- Если
X
илиY
равно*
, оно соответствует любому количеству последовательных символов. - Если
Z
равно*
, то соответствует любому количеству последовательных символов.кромевсе, что соответствуетY
. - Если
Z
равно**
, соответствует любому количеству последовательных символов. - В
r:|?=**
,X
соответствует пустой строке. - По умолчанию Zsh уже добавляет подстановочный знак в конец входных данных, тем самым замыкая круг для полного нечеткого соответствия.
Документацию можно найти здесь:http://zsh.sourceforge.net/Doc/Release/Completion-Widgets.html#Completion-Matching-Control
решение2
Это хак, пока я жду более мудрых ответов...
Я заставил свой генератор предложений выдавать такие предложения:
hw»oh hello there, world
Поскольку команда (фактически функция) находится под моим контролем, я просто удаляю весь мусор в начале:
input="${input#*»}"
Но было бы неплохо знать, как это делать правильно.