Можно ли использовать скрипт завершения табуляции Bash в zsh?
У меня есть скрипт завершения вкладки Bash для Apache Hadoop. Обычно я использую zsh в качестве своей повседневной оболочки. Когда я в этом нуждаюсь, это может быть довольно похоже на bash, но похоже, что системы завершения табуляции радикально отличаются между ними. Есть ли простой способ "преобразовать" существующие определения завершения bash-tab для работы в zsh? Я не хочу тратить на это кучу времени, но если бы это было легко, я бы сэкономил умеренное количество усилий.
5 ответов
С этой страницы (от 2010/01/05):
Zsh может обрабатывать функции завершения bash. В последней версии разработки zsh есть функция bashcompinit, которая при запуске позволит zsh читать спецификации и функции завершения bash. Это описано в справочной странице zshcompsys. Чтобы использовать его, все, что вам нужно сделать, это запустить bashcompinit в любое время после compinit. Он будет определять завершенные и компенсирующие функции, соответствующие встроенным функциям bash.
autoload bashcompinit
bashcompinit
source /path/to/your/bash_completion_file
autoload -U +X compinit && compinit
autoload -U +X bashcompinit && bashcompinit
source /path/to/your/bash_completion_script
Я бегу зш zsh 5.0.2 (x86_64-apple-darwin13.0)
без каких-либо ~/.zshrc и описанная выше последовательность работала в только что созданной оболочке zsh.
Спасибо скрипту git-extension.bash за подсказку:D
Читайте подробнее о трех строчках:
Bash имеет потрясающую встроенную поддержку автозавершения, но сценарии автозаполнения bash не работают напрямую zsh, так как среда zsh не имеет необходимых вспомогательных функций bash для автозаполнения, таких как compgen
, complete
, Это делается для того, чтобы сохранить сессию Zsh быстрой.
В эти дни zsh поставляется с соответствующими скриптами завершения, такими как compinit
а также bashcompinit
которые имеют необходимые функции для поддержки сценариев автозаполнения bash.
autoload <func_name>
: Обратите внимание, что автозагрузка определяется в zsh, а не в bash. autoload
ищет файл с именем в путях каталогов, возвращаемых fpath
команда и отмечает функцию, чтобы загрузить то же самое, когда это сначала вызвано.
- -U: игнорировать любые псевдонимы при загрузке таких функций, как compinit или bashcompinit
- + X: просто загрузите именованную функцию fow сейчас и не выполняйте ее
Например в моей системе echo $fpath
возвращается /usr/share/zsh/site-functions
а также /usr/share/zsh/5.0.5/functions
и оба compinit
а также bashcompinit
доступны по адресу /usr/share/zsh/5.0.5/functions
,
Также для большинства людей может быть только autoload -U +X bashcompinit && bashcompinit
требуется, потому что какой-то другой скрипт, такой как git autocomplete или их собственный ~/.zshrc
может делать autoload -U +X compinit && compinit
, но безопасно запустить их обоих.
Я использую Antigen в качестве менеджера плагинов Oh-My-Zsh. У меня было несколько скриптов завершения bash, написанных коллегами, которые я хотел загрузить в Zsh с помощью простого source /path/to/completion
,
У меня были некоторые проблемы, потому что кажется, что либо Antigen, либо OMZ (трудно сказать) озабочены только загрузкой сценариев завершения из своих плагинов. Я наконец-то обошел это автозагрузкой bashcompinit
а также compinit
после antigen apply
, Просто автозагрузка bashcompinit
не было достаточно
source ~/.antigen/antigen.zsh
antigen use oh-my-zsh
antigen apply
autoload -U +X compinit && compinit
autoload -U +X bashcompinit && bashcompinit
source /path/to/bash_completion
Антиген создает свой .zcompdump
файл в $ANTIGEN_COMPDUMP
который для меня был ~/.antigen/.zcompdump
Повторный вызов compinit и bashcompinit создает второй.zcompdump в $HOME/.zcompdump
Это, кажется, все работает, потому что я могу использовать дополнения, установленные /path/to/bash_completion
, Я удалил оба файла.zcompdump несколько раз, чтобы убедиться, что они восстановлены и, кажется, работают.
После перезагрузки компьютера мне пришлось несколько раз просмотреть файлы.zcompdump из-за ошибок, возникающих при попытке завершить вкладку, но я не уверен, что это связано с этой настройкой или чем-то еще. rm ~/.zcompdump && rm $ANTIGEN_COMPDUMP
и новая оболочка исправляет это для меня.
Версии, использованные на момент написания:
Antigen = v2.2.3 = d3d4ee0
Oh-my-zsh = c3b072e
Zsh = 5.3
Ответ @JatinKumar направил меня на правильный путь, но мне пришлось использовать
complete
вместо
source
. Итак все вместе:
autoload -Uz compinit && compinit
autoload -U +X bashcompinit && bashcompinit
complete -C /usr/local/bin/terraform terraform
complete -C /usr/local/aws/bin/aws_completer aws
complete -C /usr/local/bin/az az
За zsh
использовать:
compdef
compadd
Мой пример:
# bash completion for bxrun (/home/ecuomo/projects/bashx/bxrun)
_bxrun_methods() {
grep "^\s*\(function\s\+\)\?__.\+()\s*{.*$" "${1}" | while read line ; do
echo "$line" | sed "s/()\s*{.*//g" | sed "s/\s*\(function\s\+\)\?__//g"
done
}
_bxrun_lst() {
if [ -d "/home/ecuomo/projects/bashx/src/actions" ]; then
for f in /home/ecuomo/projects/bashx/src/actions/* ; do
if [ -f "${f}" ]; then
basename "${f}" | sed 's/\..*$//g'
fi
done
fi
_bxrun_methods "/home/ecuomo/projects/bashx/bxrun"
_bxrun_methods "/home/ecuomo/projects/bashx/src/bashx.sh"
}
_bxrun() {
local cur
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $( compgen -W '$( _bxrun_lst )' -- $cur ) )
}
_bxrun_zsh() {
compadd `_bxrun_lst`
}
if type complete >/dev/null 2>/dev/null; then
# bash
complete -F _bxrun bxrun
else if type compdef >/dev/null 2>/dev/null; then
# zsh
compdef _bxrun_zsh bxrun
fi; fi
Источник: мой код https://github.com/reduardo7/bashx