Conclusão do argumento de comando dos nomes de arquivos '~ / bin / *' de qualquer diretório no bash

1

Um recurso bash básico é a conclusão de comandos armazenados nos vários diretórios bin, independentemente do diretório de trabalho atual. Isso permite que os usuários mantenham comandos e binários organizados sem que eles precisem especificar caminhos completos de qualquer diretório que precise ser executado.

Exatamente como o bash fornece essa conclusão de comando antes de executar esses arquivos bin, penso, do ponto de vista do design, faz sentido esperar a mesma conclusão de comando antes de editar eles.

No meu caso particular, isso significa modificar a função de conclusão do meu editor, vi , para que inclua nomes de arquivos não apenas do meu diretório atual, mas também do meu ~/bin/ (não me importo em adicionar comandos de as outras caixas).

Uma simples modificação de esta resposta faz isso:

$ source _vi 
$ complete -f -F _vi vi

onde _vi é definido como:

_vi () 
{
    local word=${COMP_WORDS[COMP_CWORD]};
    local pat="~/bin/*"

    COMPREPLY=($(compgen -f -G "$pat" -- "~/bin/${word}"));

    i=0
    for item in "${COMPREPLY[@]}"; do
        COMPREPLY[$i]="${item##*/}"
        i+=1
    done;
    return 0;
}

Mas o vi precisa passar por caminhos completos para abrir o arquivo!

Então, minha pergunta é: Como posso completar os nomes de arquivos <%> de ~/bin/ , mas ainda passar os caminhos completos para vi ? Isso é apenas um sonho | ? Devo tentar uma abordagem totalmente diferente?

Pontos de bônus se você puder me ajudar a colorir esses ~/bin/* nomes de arquivos de maneira diferente dos arquivos que estão no diretório de trabalho quando eu obtiver todas as conclusões possíveis com vi (TAB)(TAB) !

EDITAR:

Abaixo está a função que estou usando, com base na resposta do @ roaima e sua sugestão para generalizar abaixo. É fácil adicionar acesso de conclusão independente de diretório para arquivos em diretórios diferentes dos dois (binários e arquivos de configuração) com os quais eu me importo.

_vi () 
{
    local word=${COMP_WORDS[COMP_CWORD]};
    local bin_dir="~/bin/"
    local dot_dir="~/dotfiles/"

    COMPREPLY=($(compgen -f -G "$bin_dir*" -- "$bin_dir${word}"));
    COMPREPLY+=($(compgen -f -G "$dot_dir*" -- "$dot_dir${word}"));
    return 0;
}
    
por courtyardz 10.09.2015 / 00:02

1 resposta

0

A abordagem mais fácil é evitar remover o caminho de $item ao adicioná-lo a $COMPREPLY[$i] :

_vi () 
{
    local word=${COMP_WORDS[COMP_CWORD]};
    local pat="~/bin/*"

    COMPREPLY=($(compgen -f -G "$pat" -- "~/bin/${word}"));
    return 0;
}

A lista de possíveis é mostrada sem um componente de caminho, mas na conclusão bem-sucedida o caminho é inserido.

Outra abordagem é extender vi com um script de shell que procura no diretório atual pelo nome do arquivo e, se não for encontrado, então, verifica ~/bin/ . Mas, neste ponto, começa a fazer sentido ter o editor equivalente a $CDPATH para os diretórios de conclusão, em vez de limitar o código à pesquisa de ~/bin /.

    
por 10.09.2015 / 01:13