Wie erhalte ich die Bash-Vervollständigung für Befehls-Aliase?

57

Ich möchte Tabulatorvervollständigung für meine Befehlszeilen-Aliase erhalten. Angenommen, ich habe den folgenden Alias ​​definiert:

alias apt-inst='sudo aptitude install'

Gibt es eine Möglichkeit, die von aptitude bereitgestellten Vervollständigungen zu erhalten, wenn ich die Tabulatortaste drücke? dh wenn ich 'sudo aptitude install gnumer' schreibe und tab drücke, vervollständigt aptitude dies mit gnumeric, oder wenn Ungewissheit bestand, listet es alle verfügbaren Pakete auf, die mit gnumer beginnen. Wenn ich es mit meinem Alias ​​mache, nichts - keine Vervollständigung.

levesque
quelle

Antworten:

30

Es gibt einen tollen Thread dazu in den Ubuntu-Foren . Ole J schlägt die folgende Alias-Vervollständigungsdefinitionsfunktion vor:

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"
}

Verwenden Sie diese Option, um eine Vervollständigungsfunktion für Ihren Alias ​​zu definieren, und geben Sie diese Funktion als Vervollständigungsfunktion für den Alias ​​an:

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

Ich bevorzuge es, Aliase zu verwenden, um vorhandenen Programmen immer verwendete Argumente hinzuzufügen. Zum Beispiel grepmöchte ich mit immer Geräte und Binärdateien überspringen, also erstelle ich einen Alias ​​für grep. Zum Hinzufügen neuer Befehle verwende grepbinich beispielsweise ein Shell-Skript in meinem ~/binOrdner. Befindet sich dieser Ordner in Ihrem Pfad, wird er automatisch vervollständigt.

Shawn J. Goff
quelle
2
Genial, ich hatte Angst, dass es nicht möglich sein würde.
Levesque
Beachten Sie, dass dieser Code einige Probleme aufweist. Siehe meine Antwort für ihre Erklärung und Lösung.
Tom Hale
Hinweis: Ich war für einen anderen Befehl mit dieser Technik, und ich hatte zu verwenden , complete -o default -F ...statt , complete -F ...um Dinge wie Dateiname Auto-Vervollständigung richtig arbeiten , wenn args (Bash 4.3.46) vorbei.
Joelittlejohn
28

Versuchen Sie es mit einem vollständigen Alias , der dieses Problem genau löst.

Nach der Installation können Sie mit einer allgemeinen Funktion viele Aliase wie folgt ausführen:

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

Möglicherweise möchten Sie die Datei complete_alias in jeder Bash-Instanz über .bash_profileo.ä.

Installation

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

Anwendung

source ~/.bash_completion.d/complete_alias

alias container=docker\ container
complete -F _complete_alias container

containerkann jetzt vom ursprünglichen _docker()Vervollständigungs-Handler automatisch vervollständigt werden;

$ container l<Tab>
logs  ls    

$ container s<Tab>
start  stats  stop   
Cyker
quelle
2
Angesichts der Tatsache, dass diese Software Ihnen zu gehören scheint, könnten Sie es besser machen. Fügen Sie Anweisungen zur Installation hinzu. Beschreiben Sie, was es tut und wie es verwendet wird. Ansonsten ist das nur Spam.
Muru
@muru Ich habe darüber nachgedacht, hier Code einzufügen, aber es ist wahrscheinlich länger als hier akzeptiert. Ich nehme an, die Leute haben kein Problem damit, den Install- Abschnitt in einer README-Datei zu lesen , und in diesem Fall sind es nur einige Zeilen.
Cyker
2
Es geht darum, anhand der Antwort beurteilen zu können, ob sich ein Besuch der README-Datei lohnt.
Muru
Dies ist eine angemessene Antwort und löst das Problem genau.
Ярослав Рахматуллин
1
Dies ist eine ausgezeichnete und sehr umfassende Antwort, die perfekt funktioniert, danke !. Es wurde wahrscheinlich aktualisiert, da @muru Probleme damit hatte.
Brian Topping
3

2018 antworten

Sie müssen Ihren Alias ​​zum Programm 'complete' hinzufügen. Abhängig von der Art der Autovervollständigung, die Sie erreichen möchten, müssen Sie -c oder -F verwenden.

Für die automatische Vervollständigung von Paketen:

complete -c name_of_your_alias

Für die automatische Vervollständigung von Befehlen:

complete -F name_of_your_alias

So überprüfen Sie, ob Ihr Alias ​​korrekt hinzugefügt wurde:

complete | grep name_of_your_alias

Zum Schluss, um einen Alias ​​von 'complete' zu entfernen:

complete -r name_of_your_alias

In deinem Fall:

complete -c apt-inst
Adrian Lopez
quelle
1
Bitte setzen Sie Ihre Antwort nicht in Kommentaren fort. Wenn Sie etwas zu sagen haben, bearbeiten Sie es in der Antwort.
G-Man sagt, dass Monica
2
complete -F xxxfunktioniert nicht unter OSX (es zeigt nur die Verwendung complete: usage: complete [-abcdefgjksuv] [-pr] [-o option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] [name ...]). Hast du einen Zeiger? Vielen Dank.
Anthony Kong
Verwenden Sie stattdessen Folgendes
Rich
2

Hier ist der Code von Shawn J. Goffs Antwort mit einigen Verbesserungen:

  • Behobene Syntaxfehler, hervorgehoben durch shell-checkzB den ersten "der "$@"tatsächlich beendeten Funktionsdefinitionsstrings.
  • Das wurde entfernt, return 0damit der Rückgabewert der zugrunde liegenden Funktion an den Aufrufer zurückgegeben werden kann.

.

# 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
Tom Hale
quelle
Funktioniert nicht für mich in Bash 4.3.46 Ich habe Angst. Shaun J. Goff Antwort nicht funktionieren.
Joelittlejohn
1
"Beenden" der Funktionsdefinitionszeichenfolge ist absichtlich; Es geht darum, Argumente aus der äußeren Funktion in das COMP_WORDSArray aufzunehmen. Wenn wir make-completion-wrapper _apt_get _apt_get_install apt-get installals Beispiel verwenden shift 2, $@enthält after apt-get install. Die Funktionsdefinition enthält apt-get install(die beiden wörtlichen Wörter) bei der Zuweisung COMP_WORDS.
Jeffery bis
0

Als Erweiterung zu @Giles answer benennt die folgende Komfortfunktion den Wrapper automatisch make-completion-wrapperso, dass die Vervollständigung in einer Zeile definiert werden kann:

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}
}
user84207
quelle