how to re-use existing completion with recent bash-completion?
how to re-use existing completion (for example for git) with recent versions of package bash-completion
Add the following lines to your ~/.bashrc
:
_completion_loader git
eval $(complete -p git | perl -pe 's/(\s)git$/$1git.home/')
Explanation:
bash-completion
uses a dynamic loading of completions since 1.90. So, the git
compspec unavailable before your typing git
,Space,Tab.
Try:
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
imitates git
,Space,Tab (i.e. loads a compspec for git
)
complete -p git | perl -pe 's/(\s)git$/$1git.home/'
builds a compspec for git.home
(replaces git
to git.home
in a git
's compspec)
eval
execute the resulting compspec.
Type git.home
,Space,p
Tab. You should see:
popt pull push
But git.home log
,Space,Tab produces:
fatal: Not a git repository (or any of the parent directories): .git HEAD
This message is a result of the git completion bug. There is a fix in the upstream: completion: silence "fatal: Not a git repository" error
Looks like another question:)
_githome(){
GIT_DIR=$HOME/.git.home
complete -o default -o nospace -F _git git.home
}
doesn't work as expected. You set GIT_DIR
for current session. Try with your solution:
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
updated
solution for alias git.home
, which operates with ~/.git.home
as repo.
partially based on this answer.
add to ~/.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|')"
explanation of last eval
(for other lines see answer):
we are patching the function __gitdir()
, which returns a path to the git repo dir. from:
$ type __gitdir | head -n 4
__gitdir is a function
__gitdir ()
{
if [ -z "${1-}" ]; then
to:
$ 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
i.e., if command starts with a "git.home "
, function returns $HOME/.git.home
.