web-dev-qa-db-ja.com

エイリアスを使用してbash補完を取得するにはどうすればよいですか?

適例:

私はMacでbash v3.2.17を使用しています。macports経由でbash_completionバリアントをインストールしたgitを使用しています。

git checkout m<tab>と入力すると。たとえば、masterに完成させます。

ただし、git checkoutgcoへのエイリアスがあります。 gco m<tab>と入力しても、ブランチ名がオートコンプリートされません。

理想的には、オートコンプリートがすべてのエイリアスに対して魔法のように機能することを望みます。出来ますか?それに失敗した場合、エイリアスごとに手動でカスタマイズしたいと思います。だから、どのように私はどちらに行くのですか?

182
kch

上記のコメントで述べたように、

complete -o default -o nospace -F _git_checkout gco

動作しなくなります。ただし、__git_complete git-completion.bashの関数は、次のようなエイリアスの補完を設定するために使用できます。

__git_complete gco _git_checkout
170
chris_sutter

私もこの問題に遭遇し、このコードスニペットを思いつきました。これにより、すべてのエイリアスが自動的に補完されます。すべて(または任意の)エイリアスを宣言した後に実行します。

# 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
53
Hesky Fisher

git-completion.bash行があります:

complete -o default -o nospace -F _git git

その行(および_git関数)を見て、この行を.bash_profile

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

G = 'git'というエイリアスを作成し、gitエイリアスと組み合わせて次のように入力します

$ g co <branchname>

私の特定のユースケースの簡単な修正は、git-completionに1行追加することでした。

この行のすぐ下:

__git_complete git _git

単一の「g」エイリアスを処理するために、次の行を追加しました。

__git_complete g _git
15
wonderfulthunk

理想的には、オートコンプリートがすべてのエイリアスに対して魔法のように機能することを望みます。出来ますか?

はい、 complete-alias プロジェクト(Linux)で可能です。 Macのサポートは実験的ですが、ユーザーは成功を報告しています。

12
Cyker

このフォーラムページ は解決策を示しています。

これらの行を.bashrcまたは.bash_profile

# 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=( "$@" \${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

このソリューションは balshetzerのスクリプト に似ていますが、実際にはこれだけが機能します。 (balshetzerのスクリプトには、私のエイリアスのいくつかに問題がありました。)

5
hcs42

もう1つのオプションは、~/.bash_completionファイルを使用することです。 git checkoutgcoエイリアスを作成するには、次のようにします。

_xfunc git __git_complete gco _git_checkout

次に、~/.bashrcにエイリアスのみを追加する必要があります。

alias gco='git checkout'

2行。それでおしまい。

説明:

~/bash_completionは、メインのbash_completionスクリプトの最後で取得されます。 gentooでは、/usr/share/bash-completion/bash_completionでメインスクリプトを見つけました。

_xfunc gitビットはgit-completionファイルのソースを管理するので、~/.bashrcに他のものを入れる必要はありません。

受け入れられた答えは、あなたが.git-completion.shをコピーし、私が不完全だと思う~/.bashrcファイルからそれを入手することを要求します。


PS:私はまだgit-completionスクリプト全体を私のbash環境にソースしない方法を見つけようとしています。方法を見つけたらコメントまたは編集してください。

5
kub1x

Gitエイリアスを使用することもできます。たとえば、私の~/.gitconfigファイル、次のようなセクションがあります。

[alias]
        co = checkout

したがって、git co m<TAB>、そしてそれはgit co master、これはgit checkoutコマンド。

4
mipadi

単にcompleteコマンドを見つけて、代わりにエイリアス名を持つ行を複製する必要があります。

alias d-m="docker-machine"があります。つまり、d-mdocker-machineのエイリアスとなります。

そのため、Mac(brew経由)では、完了ファイルはcd `brew --prefix`/etc/bash_completion.d/にあります。
私の場合、docker-machineというファイルを編集しました。
一番下にあるのは:

complete -F _docker_machine docker-machine

そこで、エイリアスを使用して別の行を追加しました。

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

最初に、元の完了コマンドを検索します。例:

$ complete | grep git

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

これらを起動スクリプトに追加します(例:〜/ .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

_completion_loader行は必要ありません。ただし、状況によっては、コマンドを入力してTABを初めて押した後にのみ、完了関数が動的にロードされます。したがって、元のコマンドを使用せずにエイリアス+ TABを試すと、「bash:completion:function '_docker' not found」などのエラーが表示される場合があります。

1
wisbucky

この質問には多くの答えがあり、私と同じように、多くの混乱した読者を賭けています。私の場合、Gitの異なるバージョンの複数のプラットフォームでドットファイルを動作させる必要もありました。私も_alias g=gitが、代わりにgが関数として定義されています。

これを達成するために、私はここでさまざまな答えを1つのソリューションにまとめる必要がありました。これはすでに答えを繰り返していますが、この質問に最初に来たときに持っていたのと同じように、私のボートの誰かがこの編集物を役に立つと思うかもしれません。

これは、古いGitと新しいGitの完了、Ubuntuのデフォルト、およびbrew install git MacOSで。後者の場合、Brewがインストールした完了はbashによって処理されていません(後で診断します)。

# Alias g to git

g() {
  if [[ $# > 0 ]]; then
    git "$@"
  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

alias g='git'を使用する場合、.bash_aliasesにこのコード行を追加します

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