A conclusão de bash sobrescreve a palavra atual

5

Estou tentando criar um script de conclusão do bash para o meu comando. ls tem o comportamento que eu quero. Preciso ter esse mesmo comportamento do meu comando.

Isso é o que eu recebo por ls

$ ls /home/tux/<Tab><Tab>
Downloads  Documents  Pictures
$ ls /home/tux/Do<Tab><Tab>
Downloads  Documents

Ou seja. bash mostra apenas os próximos caminhos relativamente, não absolutamente (ou seja, adiciona Downloads à lista de conclusão, mas não /home/tux/Downloads )

Eu queria escrever um script de conclusão que funcione da mesma maneira. Isso é o que eu tentei.

_testcommand ()
{
    local IFS=$'\n'
    local cur=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=( $(compgen -o bashdefault -d -- "$cur") )
    if [ "${#COMPREPLY[@]}" -ne 1 ]
    then
        # remove prefix "$cur", so the preview of paths gets shorter
        local cur_len=$(echo $cur | sed 's|/[^/]*$||' | wc -c)
        for i in ${!COMPREPLY[@]}
        do
            COMPREPLY[$i]="${COMPREPLY[i]:$cur_len}"
        done
    fi
    return 0
}

complete -o nospace -F _testcommand testcommand

No entanto, o resultado é assim:

$ testcommand /home/tux/<Tab><Tab>
Downloads  Documents  Pictures
$ testcommand /home/tux/Do<Tab>
Downloads  Documents
$ testcommand Do

Como posso fazer a minha conclusão não remover /home/tux/ da linha de comando?

Nota: acho que não consigo adicionar '-f' ou '-d' etc. à chamada complete na parte inferior. Na realidade, a conclusão deve, em alguns casos, também completar palavras em vez de caminhos.

    
por Johannes 12.08.2018 / 12:51

2 respostas

0

A maioria dos programas no diretório de conclusão bash ( pkg-config --variable=completionsdir bash-completion ) usa a função _filedir fornecida pelo próprio bash-completion. Parece legítimo reutilizar _filedir - não precisa se preocupar com sua própria implementação!

MWE:

_testcommand()
{
    # init bash-completion's stuff
    _init_completion || return

    # fill COMPREPLY using bash-completion's routine
    # in this case, accept only MarkDown and C files
    _filedir '@(md|c)'
}
complete -F _testcommand testcommand

É claro que você ainda pode usar isso ao concluir arquivos que não são:

if ...
then
    # any custom extensions, e.g. words, numbers etc
    COMPREPLY=( $(compgen ...) )
else
    # fill COMPREPLY using bash-completion's routine
    _filedir '@(md|c)'
fi

Como eu o encontrei?

Agradecemos a @csm : usando a resposta deles, confira type _longopt , que chama _filedir .

    
por 18.08.2018 / 12:48
2

Você pode verificar qual função de conclusão é usada por "ls": complete -p | grep ls . E você pode verificar a função com: type _longopt (o resultado do comando anterior). Na função _longopt você pode encontrar a função _filedir .

E, finalmente, um artigo interessante sobre conclusão: link

    
por 17.08.2018 / 13:49