如何让 bash 完成以使用别名?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/342969/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I get bash completion to work with aliases?
提问by kch
Case in point:
案例:
I'm a on mac with bash v3.2.17, I'm using git installed via macports with the bash_completion variant.
我在 mac 上使用 bash v3.2.17,我正在使用通过 macports 安装的 git 和 bash_completion 变体。
When I type git checkout m<tab>
. for example, I get it completed to master
.
当我输入git checkout m<tab>
. 例如,我把它完成到master
.
However, I've got an alias to git checkout
, gco
. When I type gco m<tab>
, I don't get the branch name autocompleted.
但是,我有一个别名git checkout
,gco
。当我输入时gco m<tab>
,我没有自动完成分支名称。
Ideally I'd like autocompletion to just magically work for all my aliases. Is it possible? Failing that, I'd like to manually customize it for each alias. So, how do I go about either?
理想情况下,我希望自动完成功能可以神奇地为我所有的别名工作。是否可以?否则,我想为每个别名手动自定义它。那么,我该怎么办呢?
采纳答案by chris_sutter
As stated in the comments above,
正如上面的评论所述,
complete -o default -o nospace -F _git_checkout gco
will no longer work. However, there's a __git_complete
function in git-completion.bash which can be used to set up completion for aliases like so:
将不再起作用。但是,__git_complete
git-completion.bash 中有一个函数可用于为别名设置完成,如下所示:
__git_complete gco _git_checkout
回答by Hesky Fisher
I ran into this problem as well and came up with this code snippet. This will automatically give you completion for all aliases. Run it after declaring all (or any) alias.
我也遇到了这个问题并想出了这个代码片段。这将自动为您完成所有别名。在声明所有(或任何)别名后运行它。
# wrap_alias takes three arguments:
# : The name of the alias
# : The command used in the alias
# : 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=""
local aliased_command=""
local alias_arguments=""
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 '\'''\'' /')"
unset wrap_alias
回答by Chris Lloyd
In git-completion.bash
there is a line:
在git-completion.bash
有一行:
complete -o default -o nospace -F _git git
Looking at that line (and the _git function) you can add this line to your .bash_profile
:
查看该行(和 _git 函数),您可以将此行添加到您的.bash_profile
:
complete -o default -o nospace -F _git_checkout gco
回答by wonderfulthunk
I have aliased g='git', and combined with my git aliases I type things like
我给 g='git' 取了别名,并结合我的 git 别名输入了诸如
$ g co <branchname>
The simpler fix for my specific use case was to add a single line to git-completion.
对于我的特定用例,更简单的解决方法是向 git-completion 添加一行。
Right below this line:
就在这条线的正下方:
__git_complete git _git
I added this line to handle my single 'g' alias:
我添加了这一行来处理我的单个“g”别名:
__git_complete g _git
回答by Cyker
Ideally I'd like autocompletion to just magically work for all my aliases. Is it possible?
理想情况下,我希望自动完成功能可以神奇地为我所有的别名工作。是否可以?
Yes, it is possible with the complete-aliasproject (on Linux). Support for Mac is experimental but users have reported success.
是的,完全别名项目(在 Linux 上)是可能的。对 Mac 的支持是实验性的,但用户报告说是成功的。
回答by mipadi
You could also try using Git aliases. For example, in my ~/.gitconfig
file, I have a section that looks like this:
您也可以尝试使用 Git 别名。例如,在我的~/.gitconfig
文件中,我有一个如下所示的部分:
[alias]
co = checkout
So you could type git co m<TAB>
, and that should expand to git co master
, which is the git checkout
command.
所以你可以输入git co m<TAB>
,它应该扩展到git co master
,这是git checkout
命令。
回答by hcs42
This forum pageshows a solution.
这个论坛页面显示了一个解决方案。
Put these lines into your .bashrc
or .bash_profile
:
将这些行放入您的.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 ) that will complete
# the 'agi' alias. (complete -F _apt_get_install agi)
#
function make-completion-wrapper () {
local function_name=""
local arg_count=$(($#-3))
local comp_function_name=""
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
This solution is similar to balshetzer's script, but only this one actually works for me. (balshetzer's script had problems with some of my aliases.)
这个解决方案类似于balshetzer's script,但只有这个对我有用。(balshetzer 的脚本对我的一些别名有问题。)
回答by kub1x
One more option is to use ~/.bash_completion
file. To create the gco
alias for git checkout
just put this in there:
另一种选择是使用~/.bash_completion
文件。要创建gco
别名git checkout
只是把它放在那里:
_xfunc git __git_complete gco _git_checkout
Then in ~/.bashrc
you have to put just the alias itself:
然后~/.bashrc
你必须只放别名本身:
alias gco='git checkout'
Two lines. That's it.
两条线。就是这样。
Explanation:
解释:
The ~/bash_completion
gets sourced at the end of the main bash_completion script. In gentoo I found the main script in /usr/share/bash-completion/bash_completion
.
在~/bash_completion
被在主bash_completion脚本的末尾来源。在 gentoo 中,我在/usr/share/bash-completion/bash_completion
.
The _xfunc git
bit takes care of sourcing the git-completion
file for you so you don't need to put anything else in ~/.bashrc
.
该_xfunc git
位负责git-completion
为您获取文件,因此您无需在~/.bashrc
.
The accepted answer require you to copy .git-completion.sh
and source it from your ~/.bashrc
file which I find lame.
接受的答案要求您.git-completion.sh
从~/.bashrc
我发现蹩脚的文件中复制并获取它。
PS: I'm still trying to figure out how not to source the whole git-completion
script into my bash environment. Please comment or edit if you find a way.
PS:我仍在试图弄清楚如何不将整个git-completion
脚本源到我的 bash 环境中。如果您找到方法,请发表评论或编辑。
回答by luckydonald
You just have to find the complete
command and duplicate the line having the alias name instead.
您只需要找到complete
命令并复制具有别名的行。
I have alias d-m="docker-machine"
. In words, d-m
shall be the alias for docker-machine
.
我有alias d-m="docker-machine"
。换句话说,d-m
应是 的别名docker-machine
。
So on Mac (via brew), the completion files are in cd `brew --prefix`/etc/bash_completion.d/
.
For my case I edited the file called docker-machine
.
All the way at the bottom there was:
所以在 Mac 上(通过 brew),完成文件在cd `brew --prefix`/etc/bash_completion.d/
.
就我而言,我编辑了名为docker-machine
.
一直在底部有:
complete -F _docker_machine docker-machine
So I just added another line, with my alias:
所以我只是用我的别名添加了另一行:
complete -F _docker_machine docker-machine
complete -F _docker_machine d-m
回答by wisbucky
First, look up the original completion command. Example:
首先,查找原始完成命令。例子:
$ complete | grep git
complete -o bashdefault -o default -o nospace -F __git_wrap__git_main git
Now add these to your startup script (e.g. ~/.bashrc):
现在将这些添加到您的启动脚本中(例如 ~/.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
The _completion_loader
line may not be required. But for some situations, the completion function is only loaded dynamically after you type the command and press TAB
the first time. So if you haven't used the original command, and try the alias + TAB
, you may get an error like "bash: completion: function '_docker' not found".
_completion_loader
可能不需要该行。但是在某些情况下,完成功能只有在您键入命令并TAB
第一次按下后才会动态加载。因此,如果您没有使用原始命令,并尝试使用别名 + TAB
,您可能会收到类似“bash: completion: function '_docker' not found”的错误。