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

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

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 completarlo y que se parece a lo 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 escribo, command f[tab][tab]aparece foo:bar y foo:foo en la lista, pero ninguno se completa en mi línea de comando (porque aún 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 agregar un espacio) para permitirme escribir bo fy luego tabular nuevamente para finalizar el comando. El problema del ejemplo es solo para mostrar lo que quiero decir... en el caso real, las combinaciones de prefijo:sufijo son bastante largas. , 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 conoce alguna forma de completar bash para que funcione de esta manera?

Respuesta1

Puede utilizar el siguiente código (reemplacé sus opciones para foo:baz foo:qux bar:eat bar:eggaclarar):

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, commandtabpuede obtener la lista del primer nivel foo: bar:y cuando escribe, ftabtabobtiene la lista de finalización para el segundo nivel baz qux. Luego, puede escribir qtabpara obtener la línea de comando completa command foo:qux.

Espero eso ayude.

información relacionada