obtendo conclusões insensíveis a maiúsculas e minúsculas com o compgen no bash

2

Estou tentando fazer com que meu comando (devmode2) conclua automaticamente com o bash trabalhando com compgen -W , meu bashrc tem:

_devmode2() {
    COMPREPLY=()
    local sonames=$(devmode2 --auto --current "${COMP_CWORD}" -- ${COMP_WORDS[@]})
    COMPREPLY=($(compgen -W "${sonames}" -- ${COMP_WORDS[COMP_CWORD]}))
}
complete -F _devmode2 devmode2

Um exemplo de preenchimento automático

$ devmode2 g<tab>

resulta em sonames com os seguintes valores:

game-life-adv
game-life-sparse
getopt-alt
git-workflow
git-workflow-extra
github-testers
group-git
group-git-ivan
Group-Git-Taggers-Maven
Group-Git-Taggers-Node
Group-Git-Taggers-Perl
Group-Git-Taggers-Ruby

mas minha conclusão automática resulta nas seguintes sugestões:

game-life-adv       game-life-sparse    getopt-alt          github-testers      git-workflow        git-workflow-extra  group-git           group-git-ivan

Como posso obter todos os valores que eu passo para compgen de volta?

    
por Ivan Wills 21.05.2015 / 17:27

1 resposta

0

Até onde eu sei, compgen não tem a opção de fazer a filtragem sem distinção entre maiúsculas e minúsculas da lista de opções que você fornece.

Existe uma variável readline que você pode definir para fazer com que a conclusão do nome do arquivo não diferencie maiúsculas de minúsculas:

bind "set completion-ignore-case on"

mas isso não afeta o comportamento de compgen , por isso provavelmente não se aplicará à conclusão programável. (Seu comportamento é um pouco estranho com nomes de arquivos também.)

Isso deixa você com a possibilidade de fazer sua própria filtragem, em vez de usar compgen (ou em conjunto com compgen se você precisar de outros recursos além de filtragem, o que não é o caso em seu exemplo).

Você poderia fazer isso com uma simples iteração sobre a lista de alternativas, fazendo uma comparação de prefixo sem distinção entre maiúsculas e minúsculas, mas a seguinte pequena função deveria funcionar:

_devmode2() {
  local sonames=($(devmode2 --auto --current "${COMP_CWORD}" -- ${COMP_WORDS[@]}))
  local prefix="${COMP_WORDS[COMP_CWORD]}"
  COMPREPLY=($(printf %s\n "${sonames[@]}" |
               awk -v IGNORECASE=1 -v p="$prefix" \
                   'p==substr($0,0,length(p))'))
}

Se devmode2 gerar uma alternativa por linha, seria mais fácil usá-la apenas como entrada para awk . Além disso, o segundo argumento da função de conclusão é, até onde eu sei, sempre igual a ${COMP_WORDS[COMP_CWORD]} . Então, isso pode ser mais simples:

_devmode2() {
  COMPREPLY=($(devmode2 -auto --current "${COMP_CWORD}" -- "${COMP_WORDS[@]}" \
               awk -v IGNORECASE=1 -v p="$2" \
                   'p==substr($0,0,length(p))'))
}
    
por 22.05.2015 / 19:44