如何让bash完成与别名一起工作?

例如:

我是一个与Bash v3.2.17的Mac上,我使用通过与bash_completion变种macports安装的git。

当我inputgit checkout m<tab> 。 例如,我把它完成master

不过,我有一个git checkout的别名, gco 。 当我键入gco m<tab> ,我没有得到自动完成的分支名称。

理想情况下,我想自动完成只是神奇地为我的所有别名工作。 可能吗? 否则,我想为每个别名手动定制它。 那么,我怎么去呢?

如上述评论所述,

 complete -o default -o nospace -F _git_checkout gco 

将不再工作。 但是,在git-completion.bash中有一个__git_complete函数可以用来设置别名的完成,例如:

 __git_complete gco _git_checkout 

我遇到了这个问题,并提出了这个代码片段。 这将自动完成所有别名。 在声明所有(或任何)别名后运行它。

 # 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 

git-completion.bash有一行:

 complete -o default -o nospace -F _git git 

看着这一行(和_git函数),你可以添加这行到你的.bash_profile

 complete -o default -o nospace -F _git_checkout gco 

我有别名g ='git',并结合我的git别名我input的东西

 $ g co <branchname> 

对于我的具体使用情况,更简单的解决方法是添加一行到git完成。

在这条线的下面:

 __git_complete git _git 

我添加了这一行来处理我的单个'g'别名:

 __git_complete g _git 

理想情况下,我想自动完成只是神奇地为我的所有别名工作。 可能吗?

是的, 完全别名项目是可能的。

此论坛页面显示一个解决scheme。

将这些行放入您的.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 

这种解决scheme类似于balshetzer的脚本 ,但只有这一个实际上适合我。 (balshetzer的脚本与我的一些别名有问题。)

你也可以尝试使用Git别名。 例如,在我的~/.gitconfig文件中,我有一个部分如下所示:

 [alias] co = checkout 

所以你可以inputgit co m<TAB> ,然后扩展到git co master ,这是git checkout命令。

还有一个select是使用~/.bash_completion文件。 为git checkout创buildgco别名就把它放在那里:

 _xfunc git __git_complete gco _git_checkout 

然后在~/.bashrc你只需要放置别名本身:

 alias gco='git checkout' 

两行。 而已。

说明:

~/bash_completion源自主bash_completion脚本的末尾。 在gentoo中,我在/usr/share/bash-completion/bash_completionfind了主脚本。

_xfunc git位负责为你提供git-completion文件,所以你不需要在~/.bashrc任何东西。

被接受的答案要求你复制.git-completion.sh ,并从我find的~/.bashrc文件中find它。


PS:我仍然想弄清楚如何不把我的bash环境下的整个git-completion脚本。 请发表评论或编辑,如果你find一个方法。

你只需要findcomplete命令,并复制具有别名的行。

我有alias dm="docker-machine" 。 换句话说, dm应该是docker-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 dm