Это верно, bash_completion
это решение. Я могу рассказать вам, что у меня есть в моей Ubuntu. Я надеюсь, что на Mac все по крайней мере похоже.
Есть /etc/bash_completion
файл, источники которого /usr/share/bash-completion/bash_completion
.
В каталоге /usr/share/bash-completion
также есть completions
подкаталог. Это место для сценариев. Давайте посмотрим на eject
сценарий:
# bash completion for eject(1) -*- shell-script -*- _eject() { local cur prev words cword _init_completion || return case $prev in -h|--help|-V|--version|-c|--changerslot|-x|--cdspeed) return ;; -a|--auto|-i|--manualeject) COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) ) return ;; esac if [[ $cur == -* ]]; then COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) ) return elif [[ $prev == @(-d|--default) ]]; then return fi _cd_devices _dvd_devices } && complete -F _eject eject # ex: ts=4 sw=4 et filetype=sh
Даже не читая документацию, мы могли бы немного переработать ее и приспособить к вашему случаю. Для нас самая важная часть кода выше, где он говорит, что после того -a
, --auto
-i
или --manualeject
может быть on
или off
. В вашем случае после bugfix
вам нужно имя каталога.
(Или нет. У вас есть another-module
каталог, но вы используете anothermodule
аргумент. Пока я предполагаю, что это опечатка. Если это не так, то ответ Энтони, я думаю, укажет вам правильное направление.)
Мы могли бы как-то извлечь эти каталоги, которые вы хотите, и заменить 'on off'
, но может быть лучше использовать существующий код. После того, как я печатаю cd
, bash
autocompletes каталоги, и она работает хорошо, даже если есть пробелы или специальные символы. Итак, давайте посмотрим на _cd()
функцию; это внутри /usr/share/bash-completion/bash_completion
, я не буду вставлять это здесь. Затем кажется, что ключевой частью этой функции является _filedir -d
вызов. Непосредственно перед тем, _filedir()
как определено, мы имеем:
# This function performs file and directory completion. It's better than # simply using 'compgen -f', because it honours spaces in filenames.
Бинго.
Поэтому я скопировал eject
скрипт под именем bob
и отредактировал в виде:
# bash completion for bob -*- shell-script -*- _bob() { local cur prev words cword curdir _init_completion || return case $prev in bob) COMPREPLY=( $( compgen -W 'start stop foo bar' -- "$cur" ) ) return ;; start) COMPREPLY=( $( compgen -W 'bugfix' -- "$cur" ) ) return ;; bugfix) curdir=$(pwd) cd public/submodules/ 2>/dev/null && _filedir -d cd "$curdir" ;; esac } && complete -F _bob bob
Существующие bash
сеансы не заметят этот файл, вы должны запустить новый, bash
чтобы протестировать его.
Да, это быстрое и грязное программирование вуду, извините.
Обратите внимание, что мы спускаемся public/submodules/
и возвращаемся. Обычно я бы использовал подоболочку:
export -f _filedir ( cd … && _filedir -d )
но похоже, что так _filedir
не получится.