Comment puis-je obtenir l'achèvement de la ligne de commande bash pour compléter un argument partiel, puis fournir d'autres astuces

3

Imaginez que j'ai une commande 'commande' qui prend les arguments foo: bar foo: foo bar: bar ou bar: foo, je peux écrire un script d'achèvement de ligne de commande que je peux attribuer à mon environnement pour lui donner un achèvement qui ressemble à ce qui suit:

function _command_opt()
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="foo:bar foo:foo bar:bar bar:foo"
    if [[ ${prev: -7} == 'command' ]]
    then
        COMPREPLY=( $(compgen -W "${opts}"  -- ${cur}) );
        return 0;
    fi
}
complete -F _command_opt -o bashdefault -o default 'command'

Cependant, si je tape, les command f[tab][tab]mots foo: bar et foo: foo sont répertoriés, mais aucun n'est complété sur la ligne de commande (car ils ne sont pas encore distincts. Ce que j'aimerais accomplir, c'est que cela produira command foo:et laissera mon curseur à la fin de le mot actuel (plutôt que d'ajouter un espace) me permettant de taper ensuite puis / bou fencore tab pour terminer la commande. Le problème exemple est juste pour montrer ce que je veux dire ... le cas réel les combinaisons préfixe: suffixe sont assez longues Par exemple, 25 commandes différentes commençant par le préfixe translationupdateprocess: et translationupdateprocess est l’un des 25 préfixes de longueur égale offrant le même nombre d’options.

Est-ce que quelqu'un connaît un moyen de terminer bash pour fonctionner de cette façon?

Robert
la source

Réponses:

0

Vous pouvez utiliser le code suivant (j'ai remplacé vos options par foo:baz foo:qux bar:eat bar:eggpour clarifier):

function _command_opt()
{
  local cur cursec command opts
  COMPREPLY=()

  cur="${COMP_WORDS[COMP_CWORD]}"
  cursec=`echo ${cur} | awk -F ':' '{print $1}'`;

  command="${COMP_WORDS[1]}"
  opts="foo bar"

  case "${command}" in
    foo)
      COMPREPLY=( $(compgen -W "baz qux" -- ${cursec}) ); return 0;;
    bar)
      COMPREPLY=( $(compgen -W "eat egg" -- ${cursec}) ); return 0;;
    *) ;;
  esac

  COMPREPLY=( $(compgen -W "${opts}" -S ":" -- ${cur}) ); compopt -o nospace;
}

complete -F _command_opt -o bashdefault -o default 'command'

Lorsque vous tapez, command [tab]vous pouvez obtenir la liste du premier niveau foo: bar:et lorsque vous tapez, f[tab][tab]vous obtenez la liste d'achèvement du deuxième niveau baz qux. Ensuite, vous pouvez taper q[tab]pour obtenir la ligne de commande complète command foo:qux.

J'espère que ça aide.

Andrés Morales
la source
désolé il m'a fallu un certain temps pour revenir à cela. Très bonne réponse. Merci!
Robert