Можно ли использовать скрипт завершения табуляции 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

Другие вопросы по тегам