[英]How to enable auto-completion of git commands if you are using aliases in .bash_profile?
我在.bash_profile中具有git别名,并希望在使用这些命令时启用自动完成功能(例如:自动完成分支名称)。 如果我使用完整的git命令,这对我有用,但是当我使用别名时,它不起作用。
我听说,如果您使用通过.gitconfig配置的别名,则可能会自动完成,但是这些别名会强制使用git,而我在.bash_profile中配置的别名将“ git”替换为“ g”,这更加方便。
各种命令的bash bash_completions
通常位于bash_completions
软件包中,或者随各个命令提供。 安装它们的位置在某种程度上取决于操作系统,在Ubuntu中,它们收集在各个位置,从/etc/bash_completion
。 该脚本源自全局bash.bashrc
,最终bash.bashrc
了各种其他脚本,这些脚本定义了各种命令的完成方式。 最终,它们都调用complete
命令来定义何时调用什么完成。
git
的完成内容(再次在Ubuntu中,位置可能有所不同)被安装到/usr/share/bash-completion/completions/git
。 该文件来自git源存储库,并定义了用于完成单个命令的函数,最终定义了一个__git_complete
函数,该函数接受一个命令,并使用一个完成函数并安装该命令的完成:
__git_complete git __git_main
上面为git
添加了完成功能,以调用__git_main
(也在该文件中定义)。 由于所有补全都是源代码,因此使用的函数在您的Shell中都可用,因此您可以使用同一调用将git补全添加到别名中:
__git_complete g __git_main
如果您的别名改用某个git子命令,请使用该文件中定义的各种子命令补全之一。 如果您使用别名ga
表示git add
,则可以使用_git_add
来代替:
__git_complete ga _git_add
请注意, __git_complete
函数(可能是该文件中的所有函数)是私有的,不能直接使用。 该功能带有相应的警告标记:
这不是公共功能。 使用风险自负。
从根本bash_completions
,这意味着更新git
和/或bash_completions
可能会更改完成文件以及上述函数的命名方式和工作方式,这可能会破坏您的设置。 因此,只有准备好经常重做该设置时,才应使用以上内容。
还要注意,您可能必须从.bashrc
或.profile
显式获取该git完成文件,以使这些功能可用:
source /usr/share/bash-completion/completions/git
某些git补全实际上会检查当前命令行以确定下一步要完成什么。 可以完成远程控制或引用规范的任何示例,例如,获取,拉取,远程和推送。 在这种情况下,仅用相应的函数来完成别名是不够的,因为别名将隐藏实际的git命令,因此完成操作将不知道如何进行。 以评论为例:
$ alias gpr='git pull --rebase'
$ __git_complete gpr _git_pull
$ gpr o[TAB]
$ gpr origin m[TAB]
$ gpr origin m
在这种情况下,远程(在这种情况下为原点)仍然可以完成,但是refspec无法完成。 这是由于命令行上缺少“拉”命令。
这种情况无法完全解决,但是可以构建需要额外选项卡的解决方法。 定义了包装器函数,而不是直接钩接到git补全中,它首先使用所需的命令行扩展别名,然后继续进行进一步的补全:
function _gpr {
if [ $COMP_CWORD = 1 ]
then
COMPREPLY=('pull --rebase ')
return 0
fi
__git_func_wrap __git_main
}
包装函数检查当前单词是否为第一个单词,在这种情况下,将COMPREPLY
变量设置为所需的命令行扩展(有关详细信息,请参阅文档以了解编程完成信息)。 请注意最后需要的额外空间,因为该功能将使用nospace
选项安装,以防止自动插入空格。
然后将包装函数安装为所需别名的完成:
complete -o bashdefault -o default -o nospace -F _gpr gpr
-F _gpr
参数指定要调用的包装器函数,最后一个参数( gpr
)指定要完成的命令(有关其他选项,请参见完整内置文件的完整文档 )。
完成包装程序后,以上会话现在变为:
$ gpr [TAB]
$ gpr pull --rebase o[TAB]
$ gpr pull --rebase origin m[TAB]
$ gpr pull --rebase origin master
在别名之后需要一个额外的选项卡,以首先扩展到所需的命令行,该命令行先前已完全隐藏在别名中。 从那里开始,完成工作按预期进行。
请注意,由于所需的命令行现在已成为实际命令行的一部分,因此别名应仅指向git
而不是git pull --rebase
。 这也是包装函数始终将完成传递给__git_main
而不是单个子命令完成的原因。 别名定义变为:
alias gpr=git
上述特殊情况的一个不错的替代方法是将shell和git别名组合在一起。 git补全会扩展git别名(即,使用git config alias.<name> '<command>'
创建的git config alias.<name> '<command>'
),以用于补全。 为实际命令配置git别名:
$ git config --global alias.pr 'pull --rebase'
然后为git安装一个简写的shell别名:
$ alias g=git
并使用原始方法将其连接到__git_main
完成:
$ __git_complete g __git_main
允许此会话:
$ g pr o[TAB]
$ g pr origin m[TAB]
$ g pr origin master
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.