Evitar que o autocompletar bash personalizado afete o redirecionamento de io (e)

4

Eu usei complete -W 'firstdatabase databasetwo etc' mysql para salvar uma lista de bancos de dados, para que eu possa preenchê-los automaticamente usando o comando mysql .

No entanto, em muitos casos, eu digitaria mysql db < /tmp/script.sql . Como posso obter o bash para reverter para o autocomplete tradicional (nomes de arquivo) depois de ver o primeiro > ou < ?

Atualização: Eu puxei uma instalação do Ubuntu, que vem com o bash-autocomplete pré-instalado. Embora a simples instalação do mesmo pacote em nosso servidor não seja uma opção para mim, ainda posso aprender com sua implementação examinando a saída de complete -p e declare . ( alias -p tem algumas coisas legais também)

No nosso servidor, usei complete -d cd . Observo que ela sofre o mesmo problema, pois depois de < ou > , a funcionalidade complete -d persiste. No entanto, bash-autocomplete tem uma abordagem mais elaborada que resolve esse problema. Aprender como eles resolveram isso por cd (e uma infinidade de outros comandos) pode mostrar como resolver o mesmo problema que estou tendo para mysql .

Portanto, aqui está sua implementação para cd : eles usam complete -o nospace -F _cd cd , que basicamente chama a função _cd para a consulta de preenchimento automático. Aqui está a função que eles usam:

_cd ()
{ 
    local cur prev words cword;
    _init_completion || return;
    local IFS='
' i j k;
    compopt -o filenames;
    if [[ -z "${CDPATH:-}" || "$cur" == ?(.)?(.)/* ]]; then
        _filedir -d;
        return 0;
    fi;
    local -r mark_dirs=$(_rl_enabled mark-directories && echo y);
    local -r mark_symdirs=$(_rl_enabled mark-symlinked-directories && echo y);
    for i in ${CDPATH//:/'
'};
    do
        k="${#COMPREPLY[@]}";
        for j in $( compgen -d $i/$cur );
        do
            if [[ ( -n $mark_symdirs && -h $j || -n $mark_dirs && ! -h $j ) && ! -d ${j#$i/} ]]; then
                j+="/";
            fi;
            COMPREPLY[k++]=${j#$i/};
        done;
    done;
    _filedir -d;
    if [[ ${#COMPREPLY[@]} -eq 1 ]]; then
        i=${COMPREPLY[0]};
        if [[ "$i" == "$cur" && $i != "*/" ]]; then
            COMPREPLY[0]="${i}/";
        fi;
    fi;
    return 0
}

complete -o nospace -F _cd cd

A execução do código acima em uma versão recente de bash fornece os resultados desejados para cd . Agora, como isso pode ser convertido para mysql ? (ou qualquer coisa que eu normalmente usaria complete -W ?)

    
por George Bailey 04.02.2016 / 17:01

1 resposta

1

A mágica está na função _init_completion , que é definida no bash_completion file do pacote bash-completion .

Não há saída fácil. Se você deseja concluir com bom senso no bash, instale o pacote de conclusão do bash. Então defina uma função:

. /etc/bash_completion
_my_mysql () {
  local cur prev words cword
  _init_completion || return
  COMPREPLY=($(compgen -W 'firstdatabase databasetwo etc' "$cur"))
}
complete -F _my_mysql mysql
    
por 06.02.2016 / 02:17