É 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.