From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: Thiago Perrotta <tbperrotta@gmail.com>
Cc: git@vger.kernel.org, carenas@gmail.com, gitster@pobox.com,
bagasdotme@gmail.com
Subject: Re: [PATCH v8 0/2] send-email: shell completion improvements
Date: Tue, 26 Oct 2021 02:48:02 +0200 [thread overview]
Message-ID: <211026.86k0i01u3c.gmgdl@evledraar.gmail.com> (raw)
In-Reply-To: <211026.86o87c1zry.gmgdl@evledraar.gmail.com>
On Tue, Oct 26 2021, Ævar Arnfjörð Bjarmason wrote:
> On Mon, Oct 25 2021, Thiago Perrotta wrote:
>
>>> ...I think that re-indentation is better left alone for the patch
>>> readability.
>>
>> Reverted the `GetOptions` indentation. Noise is now gone :-)
>
> Thanks.
>
>>> First, in your 1/3 you're adding a \n, but in 2/3 we end up with \n\n. I
>>> think you can just skip 1/3, maybe mention "how it also has a "\n" in
>>> the commit message.
>>
>> I don't quite see how this would fit into the commit message. A comment in the
>> code seems to fit better to account for this detail. That's what I did, but if
>> you still disagree, please elaborate where in the commit message this sentence
>> should be added.
>
> Makes sense I think, will take a look.
>
>>> You then strip out "--" arguments from the combined list, but isn't this
>>> something we do need to emit? I.e. it's used as syntax by the bash
>>> completion isn't it? (I just skimmed the relevant C code in
>>> parse-options.c).
>>
>> I interpreted that standalone `--` as an extraneous / useless token. If it's
>> there intentionally, then I am reverting my stripping of it. At the end of the
>> day whether to include it or not is a small detail, but FYI, when I do:
>>
>> $ git clone -<TAB>
>>
>> in bash, nothing happens. I would have expected it to be expanded to "--"
>> because of the explicit "--", but it doesn't. Therefore my conclusion is that
>> "--" in the output of "--git-completion-helper" is useless. Am I missing
>> something? What would be the function of the standalone "--" then?
>>
>> From my local testing, whether the options are sorted or not, whether
>> they are repeated or not, whether they follow a specific order with
>> respect to "--" or not, all of those details seem not to matter. Bash
>> completion seems to handle all of those cases just fine interactively.
>
> Digging a bit more: It's for folding away options that are negated, not
> for completing "-<TAB>". See the examples at b221b5ab9b9 (completion:
> collapse extra --no-.. options, 2018-06-06).
>
>> In fact, here's another example:
>>
>> $ git init --git-completion-helper | tr ' ' '\n' | grep -C1 '^--$'
>> --no-template
>> --
>> --no-bare
>>
>> ...there are --no-* options both _before_ and _after_ the --. I really
>> cannot see the point of the -- in the output, it seems to be just noise.
>
> Right, because some --no-whatever we define because we've got a
> --whatever and it's boolean, but for others we've got a --no-whatever as
> the primary, as in th case of --no-template..
>
>> I readded -- to the output anyway since you requested it, but if it
>> needs to follow a certain spec w.r.t. ordering, we should have tests for
>> it. This specific part (the -- and the --no- order thing) of the commit
>> is something I am not keen to doing though, at least not in this patch
>> series; sorry, it already goes far beyond the scope of my original
>> intent. Anything else you ask for that is inline with the original
>> intent (like generating options programatically instead of hard-coding
>> them) I am fine with though, and in fact I believe I have addressed all
>> comments so far, if there's anything else I may have missed let me know.
>
> Yeah sorry about the confusion so far, it's also been a voyage of
> discovery for me :)
>
> This time around I tested with:
>
> diff --git a/parse-options.c b/parse-options.c
> index 6e0535bdaad..d659309c5e7 100644
> --- a/parse-options.c
> +++ b/parse-options.c
> @@ -515,8 +515,6 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
> static void show_negated_gitcomp(const struct option *opts, int show_all,
> int nr_noopts)
> {
> - int printed_dashdash = 0;
> -
> for (; opts->type != OPTION_END; opts++) {
> int has_unset_form = 0;
> const char *name;
> @@ -551,10 +549,6 @@ static void show_negated_gitcomp(const struct option *opts, int show_all,
> if (nr_noopts < 0)
> printf(" --%s", name);
> } else if (nr_noopts >= 0) {
> - if (nr_noopts && !printed_dashdash) {
> - printf(" --");
> - printed_dashdash = 1;
> - }
> printf(" --no-%s", opts->long_name);
> nr_noopts++;
> }
>
> Which will fail a test in t/t9902-completion.sh showing this specific
> behavior.
FWIW I came up with the below on top while testing this. I think your
patch series is fine and we should just take it as-is.
This edge case of "--no" behavior isn't something we support in any
sensible way already, so it can just be left for later.
But since I think I gave you some bad advice and WIP code (sorry!) early
on I think this is closer to a 1=1 mapping to parse-options.c behavior,
i.e. we split up "no" and "non-no" options, put them on either side of
the "--", but are careful to put /some/ "--no" options on the RHS.
This has at least one bug: A few options have e.g. --no-to= and --no-to,
so both "=" and "" forms.
There's also some unrelated fixes there, e.g. the existing
--dump-aliases behavior was kind of dumb for what it was trying to do,
and I changed it since it got in the way of hacking this up.
diff --git a/git-send-email.perl b/git-send-email.perl
index 04087221aa7..9d6cdf52cc3 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -120,32 +120,87 @@ sub uniq {
}
sub completion_helper {
- my ($original_opts) = @_;
- my %not_for_completion = (
- "git-completion-helper" => undef,
- "h" => undef,
+ my ($options, $no_opt) = @_;
+
+ my %fp_opt_types;
+ my (@fp_pos_opt, @fp_neg_opt);
+ my $saw_dashdash = 0;
+ my $fp_gch = Git::command('format-patch', '--git-completion-helper');
+ for my $opt (split ' ', $fp_gch) {
+ if ($opt eq '--') {
+ $saw_dashdash = 1;
+ next;
+ }
+ $opt =~ s/^--//;
+ my $str = $opt =~ s/=$//;
+ if ($saw_dashdash) {
+ push @fp_neg_opt => $opt;
+ } else {
+ push @fp_pos_opt => $opt;
+ }
+ $fp_opt_types{$opt} = $str ? '=' : '';
+ }
+
+ ## Parse options according to Getopt::Long specifications. See
+ ## "perldoc Getopt::Long".
+ my %se_opt_types;
+ my (@se_pos_opt, @se_neg_opt);
+ for my $item ([$options, \@se_pos_opt], [$no_opt, \@se_neg_opt]) {
+ my ($orig, $new) = @$item;
+ @$new = map {
+ my $type;
+ $type = '' if !$type && s/\!$//;
+ $type = '=' if !$type && s/[=:][sid]$//;
+ $type = '' if !$type; # the default
+ # We don't handle all possible Getopt::Long argument specifications
+ die "BUG: unknown argument specification for $_" if /[=:+]/;
+ $se_opt_types{$_} = $type for split /\|/;
+ split /\|/;
+ } keys %$orig;
+ }
+
+ ## Sanity check that format-patch options and send-email
+ ## options don't clash. We have existing conflicts, but should
+ ## not be adding more.
+ my %conflicting;
+ my @conflicting = qw(
+ cc
+ from
+ in-reply-to
+ no-cc
+ no-thread
+ no-to
+ quiet
+ thread
+ to
);
- my @send_email_opts = ();
-
- foreach my $key (keys %$original_opts) {
- unless (exists $not_for_completion{$key}) {
- $key =~ s/!$//;
+ @conflicting{@conflicting} = ();
+ for my $opt (@fp_neg_opt, @fp_pos_opt) {
+ next unless exists $se_opt_types{$opt};
+ next if exists $conflicting{$opt};
+ warn "BUG: have a format-patch option '$opt' clashing with send-email";
+ }
- if ($key =~ /[:=][si]$/) {
- $key =~ s/[:=][si]$//;
- push (@send_email_opts, "--$_=") foreach (split (/\|/, $key));
- } else {
- push (@send_email_opts, "--$_") foreach (split (/\|/, $key));
- }
- }
+ ## Sanity check that for a --no-foo we have a positive --foo
+ my @se_bool_neg_opt = grep { /^no-/ and $se_opt_types{$_} eq '' } keys %se_opt_types;
+ for my $opt (sort @se_bool_neg_opt) {
+ my $pos = $opt; $pos =~ s/^no-//;
+ next if exists $se_opt_types{$pos};
+ die "BUG: Should have a '$pos' corresponding to '$opt'";
}
- my @format_patch_opts = split(/ /, Git::command('format-patch', '--git-completion-helper'));
- my @opts = (@send_email_opts, @format_patch_opts);
- @opts = uniq (grep !/^$/, @opts);
- # There's an implicit '\n' here already, no need to add an explicit one.
- print "@opts";
- exit(0);
+ my @pos_opts = sort(
+ map({ "--$_$fp_opt_types{$_}" } @fp_pos_opt),
+ map({ "--$_$se_opt_types{$_}" } @se_pos_opt),
+ );
+ my @neg_opts = sort(
+ map({ "--$_$fp_opt_types{$_}" } @fp_neg_opt),
+ map({ "--$_$se_opt_types{$_}" } @se_neg_opt),
+ );
+ my @all_opts = (uniq(@pos_opts), "--", uniq(@neg_opts));
+
+ print "@all_opts\n";
+ exit;
}
# most mail servers generate the Date: header, but not all...
@@ -470,20 +525,14 @@ sub config_regexp {
read_config(\%known_config_keys, \%configured, "sendemail");
}
-# Begin by accumulating all the variables (defined above), that we will end up
-# needing, first, from the command line:
-
-my $help;
-my $git_completion_helper;
-my %dump_aliases_options = (
- "h" => \$help,
- "dump-aliases" => \$dump_aliases,
+my $help = 0;
+my $git_completion_helper = 0;
+my %options_no_completion = (
+ "h" => \$help,
+ "git-completion-helper" => \$git_completion_helper,
);
-$rc = GetOptions(%dump_aliases_options);
-usage() unless $rc;
-die __("--dump-aliases incompatible with other options\n")
- if !$help and $dump_aliases and @ARGV;
my %options = (
+ "dump-aliases" => \$dump_aliases,
"sender|from=s" => \$sender,
"in-reply-to=s" => \$initial_in_reply_to,
"reply-to=s" => \$reply_to,
@@ -528,9 +577,7 @@ sub config_regexp {
"dry-run" => \$dry_run,
"envelope-sender=s" => \$envelope_sender,
"thread!" => \$thread,
- "no-thread" => sub {$thread = 0},
"validate!" => \$validate,
- "no-validate" => sub {$validate = 0},
"transfer-encoding=s" => \$target_xfer_encoding,
"format-patch!" => \$format_patch,
"no-format-patch" => sub {$format_patch = 0},
@@ -538,12 +585,23 @@ sub config_regexp {
"compose-encoding=s" => \$compose_encoding,
"force" => \$force,
"xmailer!" => \$use_xmailer,
- "no-xmailer" => sub {$use_xmailer = 0},
"batch-size=i" => \$batch_size,
"relogin-delay=i" => \$relogin_delay,
- "git-completion-helper" => \$git_completion_helper,
);
-$rc = GetOptions(%options);
+# --no-* options that disable a default that's otherwise enabled by
+# default. Matters for --git-completion-helper.
+my %no_options = (
+ "no-thread" => sub {$thread = 0},
+ "no-validate" => sub {$validate = 0},
+ "no-xmailer" => sub {$use_xmailer = 0},
+);
+my @ORIG_ARGV = @ARGV;
+$rc = GetOptions(%options_no_completion, %options);
+usage() unless $rc;
+
+# Option compatibility
+die __("--dump-aliases incompatible with other options\n")
+ if $dump_aliases and @ORIG_ARGV > 1;
# Munge any "either config or getopt, not both" variables
my @initial_to = @getopt_to ? @getopt_to : ($no_to ? () : @config_to);
@@ -551,11 +609,7 @@ sub config_regexp {
my @initial_bcc = @getopt_bcc ? @getopt_bcc : ($no_bcc ? () : @config_bcc);
usage() if $help;
-my %all_options = (%options, %dump_aliases_options, %identity_options);
-completion_helper(\%all_options) if $git_completion_helper;
-unless ($rc) {
- usage();
-}
+completion_helper({%options, %identity_options}, \%no_options) if $git_completion_helper;
if ($forbid_sendmail_variables && grep { /^sendmail/s } keys %known_config_keys) {
die __("fatal: found configuration options for 'sendmail'\n" .
next prev parent reply other threads:[~2021-10-26 0:57 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-20 0:46 [PATCH v2 0/3] send-email: shell completion improvements Thiago Perrotta
2021-08-20 0:46 ` [PATCH v2 1/3] send-email: print newline for --git-completion-helper Thiago Perrotta
2021-08-20 20:17 ` Junio C Hamano
2021-08-28 3:08 ` [PATCH v3 0/3] send-email: shell completion improvements Thiago Perrotta
2021-08-28 3:08 ` [PATCH v3 1/3] send-email: terminate --git-completion-helper with LF Thiago Perrotta
2021-08-28 3:08 ` [PATCH v3 2/3] send-email: move bash completions to core script Thiago Perrotta
2021-08-28 5:25 ` Carlo Arenas
2021-09-07 0:16 ` [PATCH] " Thiago Perrotta
2021-09-07 1:28 ` Carlo Arenas
2021-09-21 15:51 ` [PATCH v4 0/3] send-email: shell completion improvements Thiago Perrotta
2021-09-21 15:51 ` [PATCH v4 1/3] send-email: terminate --git-completion-helper with LF Thiago Perrotta
2021-09-21 15:51 ` [PATCH v4 2/3] send-email: move bash completions to core script Thiago Perrotta
2021-09-21 15:51 ` [PATCH v4 3/3] send-email docs: add format-patch options Thiago Perrotta
2021-09-23 14:02 ` [PATCH v4 0/3] send-email: shell completion improvements Ævar Arnfjörð Bjarmason
2021-09-24 2:46 ` [PATCH v5 " Thiago Perrotta
2021-09-24 20:02 ` Ævar Arnfjörð Bjarmason
2021-09-30 3:10 ` Thiago Perrotta
2021-10-07 3:36 ` [PATCH v6 " Thiago Perrotta
2021-10-07 3:36 ` [PATCH v6 1/3] send-email: terminate --git-completion-helper with LF Thiago Perrotta
2021-10-07 3:36 ` [PATCH v6 2/3] send-email: programmatically generate bash completions Thiago Perrotta
2021-10-09 6:38 ` Carlo Marcelo Arenas Belón
2021-10-11 4:10 ` [PATCH v7 0/3] send-email: shell completion improvements Thiago Perrotta
2021-10-11 13:46 ` Ævar Arnfjörð Bjarmason
2021-10-11 17:12 ` [DRAFT/WIP PATCH] send-email: programmatically generate bash completions Thiago Perrotta
2021-10-25 21:27 ` [PATCH v8 0/2] send-email: shell completion improvements Thiago Perrotta
2021-10-25 22:44 ` Ævar Arnfjörð Bjarmason
2021-10-26 0:48 ` Ævar Arnfjörð Bjarmason [this message]
2021-10-28 16:31 ` Junio C Hamano
2021-10-25 21:27 ` [PATCH v8 1/2] send-email: programmatically generate bash completions Thiago Perrotta
2021-10-25 21:27 ` [PATCH v8 2/2] send-email docs: add format-patch options Thiago Perrotta
2021-10-11 4:10 ` [PATCH v7 1/3] send-email: terminate --git-completion-helper with LF Thiago Perrotta
2021-10-11 4:10 ` [PATCH v7 2/3] send-email: programmatically generate bash completions Thiago Perrotta
2021-10-11 4:10 ` [PATCH v7 3/3] send-email docs: add format-patch options Thiago Perrotta
2021-10-07 3:36 ` [PATCH v6 " Thiago Perrotta
2021-10-09 8:31 ` [RFC PATCH] Documentation: better document format-patch options in send-email Carlo Marcelo Arenas Belón
2021-10-09 8:57 ` Bagas Sanjaya
2021-10-09 9:32 ` Carlo Arenas
2021-10-09 11:04 ` Bagas Sanjaya
2021-10-10 21:33 ` Junio C Hamano
2021-09-24 2:46 ` [PATCH v5 1/3] send-email: terminate --git-completion-helper with LF Thiago Perrotta
2021-09-24 2:46 ` [PATCH v5 2/3] send-email: programmatically generate bash completions Thiago Perrotta
2021-09-24 2:46 ` [PATCH v5 3/3] send-email docs: add format-patch options Thiago Perrotta
2021-09-24 4:36 ` Bagas Sanjaya
2021-09-24 4:53 ` Carlo Arenas
2021-09-24 6:19 ` Bagas Sanjaya
2021-09-24 6:56 ` Carlo Arenas
2021-09-24 15:33 ` Junio C Hamano
2021-09-24 17:34 ` Carlo Arenas
2021-09-24 20:03 ` Junio C Hamano
2021-09-25 3:03 ` Bagas Sanjaya
2021-09-25 4:07 ` Junio C Hamano
2021-09-25 6:13 ` Carlo Marcelo Arenas Belón
2021-09-29 21:20 ` Junio C Hamano
2021-08-28 3:08 ` [PATCH v3 " Thiago Perrotta
2021-08-28 5:22 ` Bagas Sanjaya
2021-08-20 0:46 ` [PATCH v2 2/3] send-email: move bash completions to the perl script Thiago Perrotta
2021-08-20 0:46 ` [PATCH v2 3/3] send-email docs: mention format-patch options Thiago Perrotta
2021-08-20 20:32 ` Junio C Hamano
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=211026.86k0i01u3c.gmgdl@evledraar.gmail.com \
--to=avarab@gmail.com \
--cc=bagasdotme@gmail.com \
--cc=carenas@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=tbperrotta@gmail.com \
/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).