Say I have a git-cc
executable in PATH
. If git-cc
supports --help
, then it is easy to provide adequate completion with
complete -F _longopt git-cc
This makes $ git-cc --<TAB>
complete (as per help output). But git cc --<TAB>
won't complete (even though it runs fine). More importantly if I create a git alias to the custom subcommand, e.g. cc-sensible-defaults = cc --opt1 ...
, that also won't work, and in this case simply deleting the space (git-cc
instead of git cc
) isn't an option.
What to do? I've tried messing around with __git_complete [git-]cc _longopt
, but none of the various combinations do anything good. It seems to be for completing bash aliases (like gl = git-log
), not sub-commands. The intro in git/git-completion.bash is, as expected, not very helpful, containing the confusing
# If you have a command that is not part of git, but you would still
# like completion, you can use __git_complete:
#
# __git_complete gl git_log
#
# Or if it's a main command (i.e. git or gitk):
#
# __git_complete gk gitk
(WTH is _git_log? Did they mean _git_log, which is indeed a function? Is it some convention?)
Update:
For me, this solution just makes
<tab>
list all the alternatives every time, no completion, why? I tried_git_jump() { COMPREPLY=(diff merge grep); }
andgit jump d<tab>
but the output is just listing:diff grep merge
– Moberg
What you have to do, is remove from COMPREPLY
the words so that only one that starts with $cur
is left. If you give 3, bash will show you the list. If you reduce COMPREPLY=(diff)
then it will be auto-completed by Bash.
Taking inspiration of https://github.com/git/git/blob/master/contrib/completion/git-completion.bash#L2445 , the following works nicely:
_git_jump() { __gitcomp "diff merge grep" "" "$cur"; }
Or I think it's better to write similar code yourself, not to depend on git
:
_git_jump() { COMPREPLY=( $(compgen -W "diff merge grep" -- "${COMP_WORDS[COMP_CWORD]}") ); }
For me https://devmanual.gentoo.org/tasks-reference/completion/index.html is the best introduction how to do it.
What to do?
Just define a function that does the compiletion with leading _git_
prefix.
# you should rather use COMPREPLY+=(..) or call `__gitcomp` to append
$ _git_cc() { COMPREPLY=(-a -b); }
$ git cc <tab>
-a -b
$ git cc -
__git_complete_command () {
local command="$1"
local completion_func="_git_${command//-/_}"
...
if __git_have_func $completion_func
then
$completion_func
return 0
I've tried messing around with __git_complete
As far as I understand the __git_complete
it's the other way round - you want a normal command complete like git subcommand. For example:
$ _git_cc() { COMPREPLY=(-a -b); }
$ alias mycommand='git cc'
$ __git_complete mycommand git_cc # or __git_complete mycommand _git_cc
$ mycommand <tab>
-a -b
$ mycommand -
WTH is _git_log?
_git_log
is a function the generates completion for git log
.
Did they mean _git_log, which is indeed a function?
Yes. See __git_complete tests for existence of a function with _main
suffix or _
prefix or without any prefix/suffix.
Is it some convention?)
Yes.