Existe alguma maneira de obter o COMPREPLY como uma lista vertical de palavras em uma única linha?

4

COMPREPLY por padrão retorna uma lista de palavras separadas por espaços, mas eu gostaria de retornar uma única palavra por linha. Eu tentei colocar novas linhas no final das palavras e examinei os documentos para compgen e complete, mas não consigo encontrar nada.

Isso é possível?

EDITAR:

Desculpe, eu realmente expliquei isso mal. Eu tenho um script que está vinculado a uma função autocomplete via complete -F. Quando o usuário executa o script, a aba que bate duas vezes mostra uma lista de possíveis opções via compgen. Agora a função tem linhas de código como esta:

COMPREPLY=( $(compgen -W '$( ls ~/work/dev/jobs/ | cat )' -- $curword ) )

Quando o usuário acessa a guia, esses diretórios são exibidos como:

directory0 directory1 directory2 directory3

mas eu gostaria que eles fossem exibidos como:

directory0
directory1
directory2
directory3

Eu postei um tópico semelhante ao / r / bash e alguém sugeriu fazer

bind 'set completion-display-width 0'

que funciona e, em seguida, posso desanexá-lo com

bind 'set completion-display-width -1'

O problema agora é que, se eu desatá-lo antes que a função completa retorne, ele não terá efeito, então, eu o descompactei no script depois que o usuário pressionou enter. Isso funciona bem, mas se o usuário começar a usar o preenchimento automático e, em seguida, mudar de ideia e excluir o que foi digitado e retornar ao shell, conclusão-display-width ainda será definida como 0.

Existe outra maneira de fazer isso?

    
por phimath 09.11.2014 / 04:27

2 respostas

4

Eu sugeri alterar a variável completion-display-width readline em / r / bash , mas você não alterou t especificar que você só queria que funcionasse nesta função de conclusão.

De qualquer forma, em uma função de conclusão, você pode detectar se é disparado por TAB (COMP_TYPE == 9) ou por TAB TAB ( COMP_TYPE == 63), e se este for o caso, você pode preencher os resultados com espaços para preencher toda a largura do terminal. É a coisa menos agressiva que eu posso pensar. Seria algo parecido com isto:

_foo_complete() {
    local i file files
    files=( ~/work/dev/jobs/"$2"* )
    [[ -e ${files[0]} || -L ${files[0]} ]] || return 0
    if (( COMP_TYPE == 63 )); then
        for file in "${files[@]}"; do
            printf -v 'COMPREPLY[i++]' '%*s' "-$COLUMNS" "${file##*/}"
        done
    else
        COMPREPLY=( "${files[@]##*/}" )
    fi
}
complete -F _foo_complete foo

Em uma nota lateral, você realmente não deve analisar o resultado ls .

    
por 09.11.2014 / 23:08
3

Para modificar uma variável readline apenas para uma função de conclusão específica, você pode definir a variável readline durante a execução da função e então ter $PROMPT_COMMAND alterando-a de volta.

_foo_complete() {
    # retrieve the original value
    local width=$(bind -v | sed -n 's/^set completion-display-width //p')

    if [[ $width -ne 0 ]]; then
        # change the readline variable
        bind "set completion-display-width 0"

        # set up PROMPT_COMMAND to reset itself to its current value
        PROMPT_COMMAND="PROMPT_COMMAND=$(printf %q "$PROMPT_COMMAND")"

        # set up PROMPT_COMMAND to reset the readline variable
        PROMPT_COMMAND+="; bind 'set completion-display-width $width'"
    fi

    # whatever the function normally does follows
    COMPREPLY=(aa bb)
}
complete -F _foo_complete foo
    
por 14.02.2017 / 02:11