web-dev-qa-db-fra.com

Comment puis-je obtenir l'achèvement de bash pour les alias de commande?

Je cherche à obtenir une achèvement de l'onglet sur mes alias de ligne de commande, par exemple, disons que j'ai défini l'alias suivant:

alias apt-inst='Sudo aptitude install'

Existe-t-il un moyen d'obtenir les achèvements fournis par aptitude lorsque je frappe la touche TAB? C'est-à-dire quand j'écris 'sudo aptitude installez gniller' et frappez l'onglet, l'APTITITITUIT complète cela sur GNumeric, ou s'il y avait une incertitude répertorie tous les packages disponibles à partir de gnouser. Si je le fais en utilisant mon alias, rien - pas d'achèvement.

69
levesque

Il y a n grand fil à ce sujet sur les forums Ubunt . OLE J propose la fonction de définition d'achèvement d'alias suivant:

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=( "$@" \${COMP_WORDS[@]:1} )
      "$comp_function_name"
      return 0
    }"
  eval "$function"
  echo $function_name
  echo "$function"
}

Utilisez-le pour définir une fonction d'achèvement de votre alias, puis spécifiez cette fonction en tant que complétéom pour l'alias:

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

Je préfère utiliser des alias pour ajouter des arguments toujours utilisés aux programmes existants. Par exemple, avec grep, je souhaite toujours sauter des périphériques et des fichiers binaires, donc je fais un alias pour grep. Pour ajouter de nouvelles commandes telles que grepbin, j'utilise un script shell dans mon ~/bin dossier. Si ce dossier est sur votre chemin, il sera autocompressé.

35
Shawn J. Goff

Réponse 2018

Vous devez ajouter votre alias au programme 'complet'. Selon le type d'autocompleure que vous souhaitez réaliser, vous devez utiliser -c ou -f.

Pour le paquet automatique:

complete -c name_of_your_alias

Pour la commande automatique de commande:

complete -F name_of_your_alias

Pour vérifier si votre alias a été ajouté correctement:

complete | grep name_of_your_alias

Enfin, pour supprimer un alias de "complet":

complete -r name_of_your_alias

Dans votre cas :

complete -c apt-inst
6
Adrian Lopez

Voici le code de Réponse de Shawn J. Goff avec quelques améliorations:

  • Erreurs de syntaxe fixes surlignées par Shell-check , par exemple le premier " de "$@" réellement terminé la chaîne de définition de la fonction.
  • Enlevé le return 0 Pour que la valeur de retour de la fonction sous-jacente puisse être transmise à l'appelant.

.

# 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=( \"\$@\" \${COMP_WORDS[@]:1} )
      \"$comp_function_name\"
    }"
  eval "$function"
  # echo "$function"
}
export -f make-completion-wrapper
2
Tom Hale

En googling ce problème, j'ai fini ici, j'ai donc essayé les approches dans les autres réponses. Pour diverses raisons, je ne comprends pas réellement, ils ne se sont jamais comportés correctement dans mon Ubuntu 16.04.

Quoi de fin fonctionnait pour moi était beaucoup plus trivial que prévu. Je voulais utiliser le même auto-répertoire que rsync a pour mycommand. Par conséquent, j'ai regardé la fonction d'autocompletion, puis j'ai appelé complete en conséquence.

# 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

Disclaimer: Je ne suis pas sûr de ce qui est l'inconvénient de mon approche par rapport aux autres. J'ai principalement écrit cela car cela pourrait aider les gens où cette approche triviale pourrait suffire.

2
M.Ermatinger

Comme une extension de @giles répond, la fonction de commodité suivante nomme automatiquement l'enveloppe générée par make-completion-wrapper Pour permettre de définir l'achèvement d'une ligne:

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