git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jeff King <peff@peff.net>
To: "SZEDER Gábor" <szeder.dev@gmail.com>
Cc: Tim Jaacks <timjaacks@posteo.de>, git@vger.kernel.org
Subject: Re: Bash completion for git aliases containing nested subcommands
Date: Mon, 3 Oct 2022 18:24:12 -0400	[thread overview]
Message-ID: <YzthDLdqeQx6bEcj@coredump.intra.peff.net> (raw)
In-Reply-To: <20221003142437.GB7659@szeder.dev>

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

  parent reply	other threads:[~2022-10-03 22:28 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-03 11:45 Bash completion for git aliases containing nested subcommands Tim Jaacks
2022-10-03 14:24 ` SZEDER Gábor
     [not found]   ` <1839e62f930.285a.8a94aeaa49923dfb9a7d55a303990d0a@posteo.de>
2022-10-03 15:11     ` Tim Jaacks
2022-10-03 15:43     ` SZEDER Gábor
2022-10-03 22:24   ` Jeff King [this message]
2022-10-04 11:21     ` Tim Jaacks
2022-10-05 10:05     ` SZEDER Gábor

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YzthDLdqeQx6bEcj@coredump.intra.peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=szeder.dev@gmail.com \
    --cc=timjaacks@posteo.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).