É isso mesmo, bash_completion é uma solução. Eu posso te dizer o que eu tenho no meu Ubuntu. Espero que as coisas sejam pelo menos semelhantes no Mac.
Há /etc/bash_completion arquivo que origina /usr/share/bash-completion/bash_completion .
Em um diretório /usr/share/bash-completion , há também um subdiretório completions . Este é o lugar para scripts. Vamos ver o script 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
Mesmo sem ler a documentação, podemos fazer engenharia reversa e ajustar o seu caso. Para nós, a parte mais importante do código acima é onde ele diz que, depois de -a , --auto -i ou --manualeject , pode haver on ou off . No seu caso, depois de bugfix você precisa de um nome de diretório.
(Ou não. Você tem o diretório another-module , mas você usa o argumento anothermodule . Por enquanto eu suponho que seja um erro de digitação. Caso não seja, A resposta de Anthony apontará na direção certa, eu acho.
Poderíamos de alguma forma extrair esses diretórios que você deseja e substituir 'on off' , mas talvez seja melhor utilizar o código existente. Depois de digitar cd , bash autocomplete os diretórios e ele funciona bem, mesmo se houver espaços ou caracteres especiais. Então, vamos olhar para _cd() function; está em /usr/share/bash-completion/bash_completion , não vou colar aqui. Em seguida, parece que a parte crucial dessa função é _filedir -d invocação. Pouco antes de onde _filedir() está definido, temos:
# This function performs file and directory completion. It's better than
# simply using 'compgen -f', because it honours spaces in filenames.
Bingo.
Então, copiei o script eject com o nome bob e editei na forma de:
# 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
As sessões bash existentes não notarão este arquivo, você terá que executar um novo bash para testá-lo.
Sim, é uma programação vodu rápida e suja, desculpe.
Observe que descemos para public/submodules/ e voltamos. Normalmente eu usaria um subshell:
export -f _filedir
( cd … && _filedir -d )
mas parece que _filedir não funciona desta maneira.