我用别名它向某些程序添加一些参数。
例如:
alias git.home='git --git-dir=$HOME/.git.home/'
complete -o bashdefault -o default -o nospace -F _git git.home \
2>/dev/null || complete -o default -o nospace -F _git git.home
它适用于bash-completion v.1:2.0-1
(“debian 7 wheezy”):
tab完成参数和选项别名 git.home
以及“原始” git
。
但在输入并按下bash-completion v.1:2.1-4
("debian 8 jessie") 后,我收到此错误:git.home
tab
bash:完成:找不到函数“_git”
git
如何通过最新版本的 package重用现有的完成(例如 for ) bash-completion
?
更新
找到部分解决方案:source /usr/share/bash-completion/completions/git
之前做complete ...
但我收到另一个错误 - git.home log
+ space+tab结果:
致命:不是 git 存储库(或任何父目录):.git HEAD
答案1
如何通过最新版本的 bash-completion 包重用现有的补全(例如 git)
将以下行添加到您的~/.bashrc
:
_completion_loader git
eval $(complete -p git | perl -pe 's/(\s)git$/$1git.home/')
解释:
bash-completion
使用动态加载完成,因为1.90。因此,git
在您输入git
, Space,之前,compspec 不可用Tab。
尝试:
bash
complete -p git # bash: complete: git: no completion specification
git<space><tab>
complete -p git # complete -o bashdefault -o default -o nospace -F __git_wrap__git_main git
_completion_loader git
模仿git
, Space, Tab(即加载 的 compspec git
)
complete -p git | perl -pe 's/(\s)git$/$1git.home/'
构建一个 compspec for git.home
(替换git
为git.home
agit
的 compspec)
eval
执行生成的 compspec。
类型git.home
,Space,p
Tab。你应该看到:
popt pull push
但 git.home log
,,Space产生Tab:
致命:不是 git 存储库(或任何父目录):.git HEAD
此消息是 git 完成错误的结果。上游有一个修复:完成:沉默“致命:不是 git 存储库”错误
看起来像是另一个问题:)
_githome(){
GIT_DIR=$HOME/.git.home
complete -o default -o nospace -F _git git.home
}
没有按预期工作。您GIT_DIR
为当前会话设置。尝试使用您的解决方案:
bash
git clone git://git.debian.org/git/bash-completion/bash-completion.git ~/bash-completion
cd ~/bash-completion
git log<space><tab> # completion for current repo
git.home log<space><tab> # completion for GIT_DIR
git log<space><tab> # completion for GIT_DIR
答案2
更新
解决方案别名 git.home
,它与 repo 一起运行~/.git.home
。
部分基于这个答案。
添加~/.bashrc
:
alias git.home='git --git-dir=$HOME/.git.home/'
_completion_loader git
eval "$(complete -p git | sed -r 's/(\s)git$/\1git.home/')"
eval "$(type __gitdir |
sed '1d;1,/if/s|if|if [[ "$COMP_LINE" == "git.home "* ]]; then\necho "$HOME/.git.home"\nelif|')"
最后的解释eval
(其他线路参见回答):
我们正在修补该函数__gitdir()
,该函数返回 git repo 目录的路径。从:
$ type __gitdir | head -n 4
__gitdir is a function
__gitdir ()
{
if [ -z "${1-}" ]; then
到:
$ type __gitdir | head -n 7
__gitdir is a function
__gitdir ()
{
if [[ "$COMP_LINE" == "git.home "* ]]; then
echo "$HOME/.git.home";
else
if [ -z "${1-}" ]; then
即,如果命令以 a 开头"git.home "
,则函数返回$HOME/.git.home
。
答案3
这是一个适用于任何完成功能的通用答案。我担心其他答案的不安全性,假设单行输出由sed
or解析,perl
并且我可以在没有外部调用的情况下实现它。
# Usage: complete_as TARGET COMMAND [COMMAND...]
# Tab-complete one or more COMMANDs like TARGET
complete_as() {
_completion_loader "$1"
local completion="$(complete -p "$1")"
completion="${completion%[[:space:]]$1}"
shift
eval "$completion $@"
}
complete_as git git.home
就像旧答案中的sed
和代码一样,这用新命令 ( ) 替换了目标命令 ( ) 的最后一个实例,但我正在使用perl
$1
$2
参数替换,它查看整个内容而不是在输出的每一行上运行。这很重要,因为完成函数的输出末尾有时会有换行符(如 的情况complete -W "$(_parse_help foo)" foo
)。删除外部调用也会使速度更快,如果您经常这样做,您可能会注意到这一点。
您可以类似地构建这样的安全性(并使用 bash 替换)来修复__gitdir
类似的功能亚历山大·巴拉金的回答做。
也可以看看这个 zsh 解决方案对于同样的问题。