Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you get a bash function to autocomplete as if it were something else?

Normal autocompletion for git checkout is to perhaps display a list of branches that you can then autocomplete for. What can I do to add the same autocompletion behavior for my function that wraps git checkout?

Hypothetically:

function git_checkout () {
  git checkout $1
  do_some_custom_other_stuff
}

How do I make it so that the git_checkout function autocompletes the same as git checkout?

like image 897
pogpog Avatar asked Jan 07 '23 08:01

pogpog


1 Answers

If you run complete -p git you can see what the default completion is for git itself.

$ complete -p git
complete -o bashdefault -o default -o nospace -F __git_wrap__git_main git

The important part here is the -F __git_wrap__git_main bit.

If you inspect the __git_wrap__git_main function:

$ type __git_wrap__git_main
__git_wrap__git_main is a function
__git_wrap__git_main ()
{
    __git_func_wrap __git_main
}

You can see that it just calls the __git_main function through the __git_func_wrap function. (You can inspect that for yourself if you want.)

Looking at the __git_main function you see that it tries to look up _git_XXX functions based on the command being run and, sure enough, there's a _git_checkout function (type -t _git_checkout == function).

That function provides the completion support for git checkout. That's what you want for your custom function. So that's the function you need to have completion use.

You can't call it directly though, remember it expects a bit of setup from the __git_func_wrap call that started this all, so you need to wrap it yourself.

Which is exactly what the __git_wrap__git_main function that we started with did (for __git_main) itself.

So we write a function like that ourselves:

__git_wrap_git_checkout() {
    __git_func_wrap _git_checkout
}

and then hook it up as the completion function for your function:

complete -o bashdefault -o default -o nospace -F __git_wrap_git_checkout git_checkout

and we should be good to go.


Implementing this function as a git alias instead of an independent shell function would mean that we could take advantage of the built-in git completion support and only provide the _git_git_checkout function (the same as our __git_wrap_git_checkout function above and named this way for _git_ + alias_name which is what __git_main expects) and git would do the calling automatically.

like image 148
Etan Reisner Avatar answered Jan 08 '23 23:01

Etan Reisner