¿Cómo puedo obtener la finalización de la línea de comando bash para completar un argumento parcial y luego proporcionar más pistas?

3

Imagine que tengo un comando 'comando' que toma argumentos foo: bar foo: foo bar: bar o bar: foo Puedo escribir un script de finalización de línea de comando que puedo obtener en mi entorno para darme un aspecto similar al siguiente:

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'

Sin embargo, si command f[tab][tab]escribo, obtengo foo: bar y foo: foo en la lista, pero ninguno de los dos se completa en mi línea de comando (porque todavía no son distintos. Lo que me gustaría lograr es que esto produzca command foo:y deje mi cursor al final de la palabra actual (en lugar de añadir un espacio) para permitir que yo escribo a continuación, bo fy luego pestaña de nuevo para terminar el comando el problema ejemplo es sólo para mostrar lo que quiero decir ... el verdadero caso el prefijo:. combinaciones de sufijos son bastante largos , por lo que la finalización parcial sería realmente beneficiosa, por ejemplo, 25 comandos diferentes que comienzan con el prefijo translationupdateprocess: y translationupdateprocess es uno de los 25 prefijos diferentes igualmente largos con tantas opciones.

¿Alguien sabe de una manera de completar bash para operar de esta manera?

Robert
fuente

Respuestas:

0

Puede usar el siguiente código (reemplacé sus opciones con el foo:baz foo:qux bar:eat bar:eggfin de aclarar):

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'

Cuando escribe command [tab]puede obtener la lista del primer nivel foo: bar:y cuando escribe f[tab][tab]obtiene la lista de finalización para el segundo nivel baz qux. Luego, puede escribir q[tab]para obtener la línea de comando completa command foo:qux.

Espero eso ayude.

Andrés Morales
fuente
lo siento, me tomó un tiempo volver a esto. Gran respuesta. ¡Gracias!
Robert