it-swarm-es.tech

¿Cómo obtengo la finalización de bash para los alias de comando?

Estoy buscando obtener la finalización de tabulación en mis alias de línea de comando, por ejemplo, digamos que definí el siguiente alias:

alias apt-inst='Sudo aptitude install'

¿Hay alguna manera de obtener las terminaciones proporcionadas por aptitude cuando presiono la tecla tab? es decir, cuando escribo 'Sudo aptitude install gnumer' y presiono la pestaña, aptitude completa esto en gnumeric, o si hubo incertidumbre, enumera todos los paquetes disponibles que comienzan con gnumer. Si lo hago usando mi alias, nada, sin completar.

69
levesque

Hay n gran hilo sobre esto en los foros de Ubunt . Ole J propone la siguiente función de definición de finalización de alias:

function make-completion-wrapper () {
  local function_name="$2"
  local arg_count=$(($#-3))
  local comp_function_name="$1"
  shift 2
  local function="
    function $function_name {
      ((COMP_CWORD+=$arg_count))
      COMP_WORDS=( "[email protected]" \${COMP_WORDS[@]:1} )
      "$comp_function_name"
      return 0
    }"
  eval "$function"
  echo $function_name
  echo "$function"
}

Úselo para definir una función de finalización para su alias, luego especifique esa función como completadora para el alias:

make-completion-wrapper _apt_get _apt_get_install apt-get install
complete -F _apt_get_install apt-inst

Prefiero usar alias para agregar argumentos siempre usados ​​a los programas existentes. Por ejemplo, con grep, siempre quiero omitir dispositivos y archivos binarios, así que hago un alias para grep. Para agregar nuevos comandos como grepbin, utilizo un script de Shell en mi ~/bin carpeta. Si esa carpeta está en su camino, se completará automáticamente.

35
Shawn J. Goff

Pruebe complete-alias , que resuelve este problema exactamente. ( Descargo de responsabilidad : ¡Soy el autor de complete_alias)

Después de instalarlo, puede usar una función genérica para completar muchos alias como este:

complete -F _complete_alias <myalias1>
complete -F _complete_alias <myalias2>
complete -F _complete_alias <myalias3>

Es posible que desee obtener el archivo complete_alias En cada instancia de bash a través de .bash_profile O similar.

installation

mkdir ~/.bash_completion.d
curl https://raw.githubusercontent.com/cykerway/complete-alias/master/complete_alias \
     > ~/.bash_completion.d/complete_alias

solicitud

source ~/.bash_completion.d/complete_alias

alias container=docker\ container
complete -F _complete_alias container

container ahora puede completarse automáticamente con el controlador de finalización original _docker();

$ container l<Tab>
logs  ls    

$ container s<Tab>
start  stats  stop   
37
Cyker

respuesta 2018

Debe agregar su alias al programa 'completo'. Dependiendo del tipo de autocompletado que desee lograr, debe usar -c o -F.

Para autocompletar paquetes:

complete -c name_of_your_alias

Para el autocompletado de comandos:

complete -F name_of_your_alias

Para verificar si su alias se agregó correctamente:

complete | grep name_of_your_alias

Finalmente, para eliminar un alias de 'complete':

complete -r name_of_your_alias

En su caso:

complete -c apt-inst
6
Adrian Lopez

Aquí está el código de respuesta de Shawn J. Goff con algunas mejoras:

  • Se corrigieron los errores de sintaxis resaltados por Shell-check , por ejemplo, el primer " de "[email protected]" en realidad finalizó la cadena de definición de función.
  • Retiró el return 0 para que el valor de retorno de la función subyacente se pueda devolver al llamador.

.

# Wraps a completion function, eg for use with an alias.
# Usage:
# make-completion-wrapper <actual completion function> <name of new func.>
#                         <command name> <list supplied arguments>
# eg.
#   alias agi='apt-get install'
#   make-completion-wrapper _apt_get _apt_get_install apt-get install
#     # defines a function called _apt_get_install (that's $2) that will
#     # complete the 'agi' alias. 
#   complete -F _apt_get_install agi
function make-completion-wrapper {
  local function_name="$2"
  local arg_count=$(( $#-3 ))
  local comp_function_name="$1"
  shift 2
  local function="function $function_name {
      (( COMP_CWORD += $arg_count ))
      COMP_WORDS=( \"\[email protected]\" \${COMP_WORDS[@]:1} )
      \"$comp_function_name\"
    }"
  eval "$function"
  # echo "$function"
}
export -f make-completion-wrapper
2
Tom Hale

Al buscar en Google este problema, terminé aquí, así que probé los enfoques en las otras respuestas. Por varias razones que no entiendo, nunca se comportaron correctamente en mi Ubuntu 16.04.

Lo que al final funcionó para mí fue mucho más trivial de lo esperado. Quería usar el mismo autocompletado que rsync tiene para mycommand. Por lo tanto, busqué la función de autocompletado y luego llamé complete en consecuencia.

# Lookup of name of autocompletion function used for rsync
complete -p rsync
# Returns: complete -o nospace -F _rsync rsync

# Sourcing the rsync functions before, then using the same function for 'mycommand'
. /usr/share/bash-completion/completions/rsync
complete -o nospace -F _rsync mycommand

Descargo de responsabilidad: no estoy seguro de cuál es la desventaja de mi enfoque en comparación con los demás. Principalmente escribí esto, ya que podría ayudar a las personas donde este enfoque trivial podría ser suficiente.

2
M.Ermatinger

Como una extensión de la respuesta @Giles, la siguiente función de conveniencia nombra automáticamente el contenedor generado por make-completion-wrapper para permitir definir la finalización en una línea:

function complete-alias  {
    # uses make-completion-wrapper: https://unix.stackexchange.com/a/4220/50978
    # example usage
    # complete-alias _pass pshow pass show
    # complete-alias _pass pgen pass generate

    EXISTING_COMPLETION_FN=${1} && shift
    ALIAS=${1} && shift
    AUTOGEN_COMPLETION_FN="__autogen_completion_${ALIAS}"
    make-completion-wrapper ${EXISTING_COMPLETION_FN} ${AUTOGEN_COMPLETION_FN} ${*}
    complete -F ${AUTOGEN_COMPLETION_FN} ${ALIAS}
}
1
user84207