it-swarm.com.de

Wie bekomme ich bash Completion, um mit Aliasen zu arbeiten?

Fallbeispiel: 

Ich bin ein Mac mit bash v3.2.17, ich verwende git über macports mit der bash_completion-Variante.

Wenn ich git checkout m<tab> eingebe. Zum Beispiel bekomme ich es zu master.

Ich habe jedoch einen Alias ​​für git checkout, gco. Wenn ich gco m<tab> eingebe, erhalte ich den Namen der Verzweigung nicht automatisch.

Im Idealfall möchte ich, dass die Autovervollständigung für alle meine Aliasnamen magisch funktioniert. Ist es möglich? Andernfalls möchte ich es manuell für jeden Alias ​​anpassen. Also, wie gehe ich vor?

176
kch

Wie in den obigen Kommentaren erwähnt,

complete -o default -o nospace -F _git_checkout gco

wird nicht mehr funktionieren. Es gibt jedoch eine __git_complete-Funktion in git-completion.bash, mit der die Vervollständigung für Aliasnamen wie folgt festgelegt werden kann:

__git_complete gco _git_checkout
162
chris_sutter

Ich bin auch auf dieses Problem gestoßen und habe mir dieses Code-Snippet ausgedacht. Dadurch erhalten Sie automatisch einen Abschluss für alle Aliase. Führen Sie es aus, nachdem Sie alle Aliasnamen (oder einen beliebigen Alias) deklariert haben.

# wrap_alias takes three arguments:
# $1: The name of the alias
# $2: The command used in the alias
# $3: The arguments in the alias all in one string
# Generate a wrapper completion function (completer) for an alias
# based on the command and the given arguments, if there is a
# completer for the command, and set the wrapper as the completer for
# the alias.
function wrap_alias() {
  [[ "$#" == 3 ]] || return 1

  local alias_name="$1"
  local aliased_command="$2"
  local alias_arguments="$3"
  local num_alias_arguments=$(echo "$alias_arguments" | wc -w)

  # The completion currently being used for the aliased command.
  local completion=$(complete -p $aliased_command 2> /dev/null)

  # Only a completer based on a function can be wrapped so look for -F
  # in the current completion. This check will also catch commands
  # with no completer for which $completion will be empty.
  echo $completion | grep -q -- -F || return 0

  local namespace=alias_completion::

  # Extract the name of the completion function from a string that
  # looks like: something -F function_name something
  # First strip the beginning of the string up to the function name by
  # removing "* -F " from the front.
  local completion_function=${completion##* -F }
  # Then strip " *" from the end, leaving only the function name.
  completion_function=${completion_function%% *}

  # Try to prevent an infinite loop by not wrapping a function
  # generated by this function. This can happen when the user runs
  # this twice for an alias like ls='ls --color=auto' or alias l='ls'
  # and alias ls='l foo'
  [[ "${completion_function#$namespace}" != $completion_function ]] && return 0

  local wrapper_name="${namespace}${alias_name}"

  eval "
function ${wrapper_name}() {
  let COMP_CWORD+=$num_alias_arguments
  args=( \"${alias_arguments}\" )
  COMP_WORDS=( $aliased_command \${args[@]} \${COMP_WORDS[@]:1} )
  $completion_function
  }
"

  # To create the new completion we use the old one with two
  # replacements:
  # 1) Replace the function with the wrapper.
  local new_completion=${completion/-F * /-F $wrapper_name }
  # 2) Replace the command being completed with the alias.
  new_completion="${new_completion% *} $alias_name"

  eval "$new_completion"
}

# For each defined alias, extract the necessary elements and use them
# to call wrap_alias.
eval "$(alias -p | sed -e 's/alias \([^=][^=]*\)='\''\([^ ][^ ]*\) *\(.*\)'\''/wrap_alias \1 \2 '\''\3'\'' /')"

unset wrap_alias
52
Hesky Fisher

In git-completion.bash gibt es eine Zeile:

complete -o default -o nospace -F _git git

Wenn Sie sich diese Zeile (und die _git-Funktion) ansehen, können Sie diese Zeile zu Ihrem .bash_profile hinzufügen:

complete -o default -o nospace -F _git_checkout gco
18
Chris Lloyd

Ich habe al = git 'git', und zusammen mit meinen git-Aliasnamen schreibe ich Dinge wie 

$ g co <branchname>

Die einfachere Lösung für meinen speziellen Anwendungsfall bestand darin, eine einzige Zeile zu git-completion hinzuzufügen.

Direkt unterhalb dieser Zeile:

__git_complete git _git

Ich habe diese Zeile hinzugefügt, um meinen einzigen 'g'-Alias ​​zu behandeln:

__git_complete g _git
15
wonderfulthunk

Im Idealfall möchte ich, dass die Autovervollständigung für alle meine Aliasnamen magisch funktioniert. Ist es möglich?

Ja, mit dem complete-alias -Projekt (unter Linux) ist es möglich. Die Unterstützung für Mac ist experimentell, die Benutzer berichten jedoch von Erfolg.

12
Cyker

Diese Forumsseite zeigt eine Lösung.

Fügen Sie diese Zeilen in Ihren .bashrc oder .bash_profile ein:

# Author.: Ole J
# Date...: 23.03.2008
# License: Whatever

# Wraps a completion function
# 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"
    return 0
}"
    eval "$function"
}

# and now the commands that are specific to this SO question

alias gco='git checkout'

# we create a _git_checkout_mine function that will do the completion for "gco"
# using the completion function "_git"
make-completion-wrapper _git _git_checkout_mine git checkout

# we tell bash to actually use _git_checkout_mine to complete "gco"
complete -o bashdefault -o default -o nospace -F _git_checkout_mine gco

Diese Lösung ähnelt dem Skript von balshetzer , aber nur diese funktioniert für mich. (Das Skript von Balshetzer hatte Probleme mit einigen meiner Aliase.)

5
hcs42

Sie können auch versuchen, Git-Aliase zu verwenden. In meiner ~/.gitconfig-Datei habe ich beispielsweise einen Abschnitt, der wie folgt aussieht:

[alias]
        co = checkout

Sie könnten also git co m<TAB> eingeben, und dies sollte zu git co master erweitert werden. Dies ist der Befehl git checkout.

4
mipadi

Eine weitere Option ist die Verwendung von ~/.bash_completion-Datei. Um den gco-Alias ​​für git checkout zu erstellen, geben Sie diesen einfach dort ein: 

_xfunc git __git_complete gco _git_checkout

Dann müssen Sie in ~/.bashrc nur den Alias ​​selbst eingeben: 

alias gco='git checkout'

Zwei Linien. Das ist es. 

Erklärung:

Der ~/bash_completion wird am Ende des main bash_completion-Skripts bezogen. In gentoo fand ich das Hauptskript in /usr/share/bash-completion/bash_completion

Das _xfunc git-Bit kümmert sich darum, die git-completion-Datei für Sie zu finden, sodass Sie nichts anderes in ~/.bashrc eingeben müssen. 

Die akzeptierte Antwort erfordert, dass Sie .git-completion.sh kopieren und von Ihrer ~/.bashrc-Datei beziehen, die ich für lahm finde. 


PS: Ich versuche immer noch herauszufinden, wie ich das gesamte git-completion-Skript nicht in meine bash-Umgebung packen kann. Bitte kommentieren oder bearbeiten, wenn Sie einen Weg finden. 

4
kub1x

Sie müssen nur den Befehl complete finden und stattdessen die Zeile mit dem Aliasnamen duplizieren. 

Ich habe alias d-m="docker-machine". In Worten ist d-m der Alias ​​für docker-machine

Auf einem Mac (via Brew) befinden sich die Abschlussdateien in cd `brew --prefix`/etc/bash_completion.d/.
Für meinen Fall habe ich die Datei mit dem Namen docker-machine bearbeitet.
Der ganze Weg unten war:

complete -F _docker_machine docker-machine

Also habe ich nur noch eine Zeile mit meinem Alias ​​hinzugefügt:

complete -F _docker_machine docker-machine
complete -F _docker_machine d-m
2
luckydonald

Es gibt viele Antworten auf diese Frage und ich wette, wie ich, viele verwirrte Leser. Für meinen Fall hatte ich auch die Anforderung, dass meine Dotfiles auf mehreren Plattformen mit verschiedenen Git-Versionen funktionieren. Ich alias g=git auch nicht, sondern g als Funktion definiert.

Um dies zu erreichen, musste ich hier verschiedene Antworten zu einer Lösung zusammenfassen. Obwohl dies die bereits gegebenen Antworten wiederholt, dachte ich, dass jemand in meinem Boot diese Zusammenstellung nützlich finden könnte, wie ich es getan hätte, als ich zum ersten Mal auf diese Frage kam.

Dies setzt ältere und neuere Git-Vervollständigungen, Ubuntu-Standardeinstellungen und brew install git unter MacOS voraus. Im späteren Fall wurden die installierten Fertigstellungen des Suds nicht von Bash verarbeitet (etwas, das ich später diagnostizieren werde).

# Alias g to git

g() {
  if [[ $# > 0 ]]; then
    git "[email protected]"
  else
    git status -sb
  fi
}

# Preload git completion in Ubuntu which is normally lazy loaded but we need
# the __git_wrap__git_main function available for our completion.
if [[ -e /usr/share/bash-completion/completions/git ]]; then
  source /usr/share/bash-completion/completions/git
Elif [[ -e /usr/local/etc/bash_completion.d/git-completion.bash ]]; then
  source /usr/local/etc/bash_completion.d/git-completion.bash
fi

if command_exists __git_complete; then
  __git_complete g _git
Elif command_exists __git_wrap__git_main; then
  complete -o bashdefault -o default -o nospace -F __git_wrap__git_main g
fi
0
Sukima

Suchen Sie zuerst den ursprünglichen Beendigungsbefehl. Beispiel:

$ complete | grep git

complete -o bashdefault -o default -o nospace -F __git_wrap__git_main git

Fügen Sie diese nun Ihrem Startskript hinzu (z. B. ~/.bashrc):

# copy the original statement, but replace the last command (git) with your alias (g)
complete -o bashdefault -o default -o nospace -F __git_wrap__git_main g

# load dynamically loaded completion functions (may not be required)
_completion_loader git

Die _completion_loader-Zeile ist möglicherweise nicht erforderlich. In einigen Fällen wird die Beendigungsfunktion jedoch nur dynamisch geladen, wenn Sie den Befehl eingeben und zum ersten Mal TAB drücken. Wenn Sie also den ursprünglichen Befehl nicht verwendet haben und den Aliasnamen + TAB verwenden, wird möglicherweise ein Fehler wie "bash: completion: Funktion '_docker' nicht gefunden" angezeigt.

0
wisbucky

Wenn Sie alias g='git' verwenden, füge ich diese Codezeile in .bash_aliases hinzu.

complete -o default -o nospace -F _git g
0
Druta Ruslan