У меня есть сценарий завершения вкладки Bash для Apache Hadoop. Обычно я использую zsh как свою повседневную оболочку. Он имеет тенденцию быть довольно похожим на bash, когда мне это нужно, но похоже, что системы завершения табуляции радикально отличаются между ними. Есть ли простой способ «преобразовать» существующие определения завершения bash-tab для работы в zsh? Я не хочу тратить на это кучу времени, но если это будет легко, я сэкономлю умеренное количество усилий.
источник
/etc/zsh/zshrc
. Кроме того , проверьте следующие файлы в обратном порядке (перечислены в порядке их соерсед при ЗШ запуске):/etc/zsh/zshenv
,$ZDOTDIR/.zshenv
,/etc/zsh/zprofile
и$ZDOTDIR/.zprofile
(возможно~/.zprofile
) , чтобы увидеть , еслиRCS
переменная не установлена. Если это так, то это предотвратит получение следующих файлов после файла, в котором он не установлен. Наконец, проверьте оболочку для пользователя/etc/passwd
и убедитесь,zsh
что она не имеет-f
аргументов.autoload bashcompinit bashcompinit source /path/to/your/bash_completion_file
источник
complete:13: command not found: compdef
ошибку.if is-bash
вверху есть галочка._get_comp_words_by_ref
которых не определеноbashcompinit
. Однако большинство доработок не используют эту функцию.autoload -U +X compinit && compinit autoload -U +X bashcompinit && bashcompinit source /path/to/your/bash_completion_script
Я использую zsh
zsh 5.0.2 (x86_64-apple-darwin13.0)
без ~ / .zshrc и приведенная выше последовательность работала в только что созданной оболочке zsh.Спасибо скрипту git-Completion.bash за подсказку: D
Читайте подробнее о трех строках выше:
Bash имеет потрясающую встроенную поддержку автозаполнения, но скрипты автозаполнения bash не работают напрямую zsh, поскольку в среде zsh нет основных вспомогательных функций автозаполнения bash, таких как
compgen
,complete
. Это делается для того, чтобы сессия zsh оставалась быстрой.В наши дни zsh поставляется с соответствующими сценариями завершения, такими как
compinit
иbashcompinit
которые имеют необходимые функции для поддержки сценариев автозаполнения bash.autoload <func_name>
: Обратите внимание, что автозагрузка определяется в zsh, а не в bash.autoload
ищет файл с именем в пути к каталогам, возвращаемымfpath
командой, и отмечает функцию для загрузки при первом вызове.Например , на моей системе
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
требуется потому , что какой -либо другой сценарий , как мерзавца автозаполнения или их собственные~/.zshrc
может делатьautoload -U +X compinit && compinit
, но это безопасно просто запустить их обоих.источник
-U
и+X
для чего?+X foo
выполнения той же автоматической загрузки, что и при вызовеfoo
, но без его немедленного выполнения… так чтоautoload +X foo && foo
кажется полностью излишним. Вы можете объяснить, почему вы выбрали этот узор?autoload -U +X bashcompinit && bashcompinit
том, что (из-за&&
) он выполнитbashcompinit
IFF, модуль действительно найден. Нормальныйautoload foo
всегда возвращает истину. Позже, когда вы пытаетесь запуститьfoo
, то ЗШ наконец говорит вам «файл определение функции не найден». Сautoload +X
вами получите ошибку немедленно.autoload +X
загружает функцию, не выполняя ее - а это больше, чемautoload
работает без+X
. Без+X
автозагрузки даже функция не загружается; Он просто отмечает имя как ссылку на функцию, которая будет загружена позже. Фактическая загрузка не выполняется до первого вызова функции. Если вы хотите определить, успешно ли загружается названная функция , вам нужно использовать+X
для немедленного выполнения шага загрузки.Для
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
источник
Я запускаю 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
Antigen создает свой
.zcompdump
файл, в$ANTIGEN_COMPDUMP
котором у меня был~/.antigen/.zcompdump
Повторный вызов compinit и bashcompinit создает второй .zcompdump в
$HOME/.zcompdump
Это кажется всем удается, потому что я могу использовать дополнение , настроенное
/path/to/bash_completion
. Я удалил оба файла .zcompdump несколько раз, чтобы убедиться, что они восстановлены и работают.Мне приходилось перезагружать файлы .zcompdump несколько раз после перезагрузки компьютера из-за ошибок, возникающих при попытке завершения вкладки, но я не уверен, связано ли это с этой настройкой или чем-то еще.
rm ~/.zcompdump && rm $ANTIGEN_COMPDUMP
и новая оболочка исправляет это для меня.Версии, использованные на момент написания:
источник
Ответ @ 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
источник