On Mon, Oct 03, 2022 at 04:24:37PM +0200, SZEDER Gábor wrote: > > Is there a way to get the completion on the alias behave like on the > > original command? > > In general: no. Our Bash completion script is organized as one > _git_cmd() function for each git supported command. If a command has > subcommands, then its completion function looks for any of its > subcommands amond the words on the command line, and takes the > appropriate action, which is usually executing a particular arm of a > case statement. The two main issues are that in case of such an alias > there is no subcommand ("show") on the command line, and there is no > dedicated function to handle only the completion for 'git stash show'. It feels like this ought to be able to work, for the same reason that "git stash show <TAB>" works. In the non-aliased case, we call into _git_stash(), and it sees that "show" is already there on the command line. But in the aliased case, we know "show" is part of the alias but throw away that information completely, and never feed it to _git_stash() at all. I think we could do something like the patch below, though I suspect there are some dragons with more complicated aliases. I wonder if __git_aliased_command() needs to be more careful with distinguishing pure-git-command aliases from the complexity of "!" aliases. Or maybe the alias stuff is all best-effort enough that this doesn't make anything worse. diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index ba5c395d2d..f68bfcbf05 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1148,10 +1148,13 @@ __git_aliased_command () cur= for word in $cmdline; do + if test -n "$cur"; then + expansion_words+=("$word") + continue + fi case "$word" in \!gitk|gitk) cur="gitk" - break ;; \!*) : shell command alias ;; -*) : option ;; @@ -1163,14 +1166,13 @@ __git_aliased_command () \'*) : skip opening quote after sh -c ;; *) cur="$word" - break esac done done cur=$last if [[ "$cur" != "$1" ]]; then - echo "$cur" + expansion=$cur fi } @@ -3507,9 +3509,13 @@ __git_main () __git_complete_command "$command" && return - local expansion=$(__git_aliased_command "$command") + # __git_aliased_command now writes to these + local expansion + local expansion_words + __git_aliased_command "$command" if [ -n "$expansion" ]; then - words[1]=$expansion + words=("${words[0]}" "$expansion" "${expansion_words[@]}" "${words[@]:2}") + cword=$((cword + ${#expansion_words[@]})) __git_complete_command "$expansion" fi } By the way, you'll notice that the splice into "words" happens right at words[1]. That matches the earlier code that just touches words[1]. But I suspect that isn't right. If we're completing "git -p foo", for example, then the command is at word[2]. I don't know if this causes any bugs, since we get to the right completion function based on $expansion, not any value in $words. But presumably it should be __git_cmd_idx? -Peff