Come posso ottenere il completamento bash per gli alias di comando?


57

Sto cercando di ottenere il completamento di tabulazione sui miei alias da riga di comando, ad esempio, suppongo di aver definito il seguente alias:

alias apt-inst='sudo aptitude install'

C'è un modo per ottenere i completamenti forniti da aptitude quando premo il tasto Tab? cioè quando scrivo 'sudo aptitude install gnumer' e premo tab, aptitude completa questo in gnumeric, o se c'era incertezza elenca tutti i pacchetti disponibili che iniziano con gnumer. Se lo faccio usando il mio alias, niente - nessun completamento.


Risposte:


30

C'è un bel filo su questo nei forum di Ubuntu . Ole J propone la seguente funzione di definizione del completamento 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=( "$@" \${COMP_WORDS[@]:1} )
      "$comp_function_name"
      return 0
    }"
  eval "$function"
  echo $function_name
  echo "$function"
}

Usalo per definire una funzione di completamento per il tuo alias, quindi specifica quella funzione come completamento per l'alias:

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

Preferisco usare gli alias per aggiungere argomenti sempre usati ai programmi esistenti. Ad esempio, con grep, voglio sempre saltare dispositivi e file binari, quindi creo un alias per grep. Per aggiungere nuovi comandi come grepbin, uso uno script di shell nella mia ~/bincartella. Se quella cartella si trova sul tuo percorso, verrà completata automaticamente.


2
Fantastico, temevo che non sarebbe stato possibile.
Levesque,

Nota che questo codice presenta alcuni problemi. Vedi la mia risposta per la loro spiegazione e risoluzione.
Tom Hale,

Nota: stavo usando questa tecnica per un altro comando e ho dovuto usare complete -o default -F ...invece di complete -F ...far funzionare correttamente cose come il completamento automatico del nome file quando si passa args (Bash 4.3.46).
joelittlejohn,

28

Prova alias completo , che risolve esattamente questo problema.

Dopo l'installazione è possibile utilizzare una funzione generica per completare molti alias in questo modo:

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

È possibile che si desideri eseguire il source del file complete_alias in ogni istanza bash .bash_profileo simile.

installazione

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

applicazione

source ~/.bash_completion.d/complete_alias

alias container=docker\ container
complete -F _complete_alias container

containerora può essere completato automaticamente dal _docker()gestore di completamento originale ;

$ container l<Tab>
logs  ls    

$ container s<Tab>
start  stats  stop   

2
Dato che questo software sembra essere tuo, potresti fare di meglio. Aggiungi le istruzioni per installarlo. Descrivi cosa fa e come usarlo. Altrimenti questo è solo spam.
Muru,

@muru Stavo pensando di incollare un po 'di codice qui, ma probabilmente è più lungo di quanto accettato qui. Suppongo che le persone non abbiano problemi a leggere la sezione Installa in un file README e in questo caso sono solo diverse righe.
Cyker,

2
il punto è poter giudicare se vale la pena visitare il README, solo dalla risposta.
Muru,

Questa è una risposta adeguata e risolve esattamente il problema.
Ярослав Рахматуллин,

1
Questa è una risposta eccellente e molto completa che funziona perfettamente, grazie !. Probabilmente è stato aggiornato da quando @muru ha avuto problemi con esso.
Brian Topping,

3

Risposta 2018

Devi aggiungere il tuo alias al programma 'complete'. A seconda del tipo di completamento automatico che si desidera ottenere, è necessario utilizzare -c o -F.

Per il completamento automatico del pacchetto:

complete -c name_of_your_alias

Per il completamento automatico del comando:

complete -F name_of_your_alias

Per verificare se il tuo alias è stato aggiunto correttamente:

complete | grep name_of_your_alias

Infine, per rimuovere un alias da 'complete':

complete -r name_of_your_alias

Nel tuo caso:

complete -c apt-inst

1
Si prega di non continuare la risposta nei commenti. Se hai cose da dire, modificale nella risposta.
G-Man dice 'Reinstate Monica'

2
complete -F xxxnon funziona su OSX (mostra solo l'utilizzo complete: usage: complete [-abcdefgjksuv] [-pr] [-o option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] [name ...]). Hai qualche puntatore? Grazie.
Anthony Kong,


2

Ecco il codice dalla risposta di Shawn J. Goff con alcuni miglioramenti:

  • Errori di sintassi fissi evidenziate da shell-check, ad esempio, la prima "di "$@"effettivamente chiuso la stringa di definizione funzione.
  • Rimosso in return 0modo che il valore restituito della funzione sottostante possa essere restituito al chiamante.

.

# 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

Non funziona per me in Bash 4.3.46 Temo. La risposta di Shaun J. Goff fa lavoro.
joelittlejohn,

1
"Fine" della stringa di definizione della funzione è intenzionale; il punto è includere COMP_WORDSnell'array gli argomenti della funzione esterna . Se usiamo make-completion-wrapper _apt_get _apt_get_install apt-get installcome esempio, dopo shift 2, $@contiene apt-get install. La definizione della funzione include apt-get install(le due parole letterali) durante l'assegnazione COMP_WORDS.
Jeffery al

0

Come estensione alla risposta di @Giles, la seguente funzione di convenienza assegna un nome automatico al wrapper generato da make-completion-wrapperper consentire di definire il completamento in una riga:

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}
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.