aboutsummaryrefslogtreecommitdiffstats
path: root/parse-options.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2018-06-28 12:53:32 -0700
committerJunio C Hamano <gitster@pobox.com>2018-06-28 12:53:32 -0700
commit6da2d9595161441cbed1b1f579b8dd46970a8e20 (patch)
tree1bde41b69722ae519ed4c29709e6c3f0dc87d1a6 /parse-options.c
parentMerge branch 'pw/add-p-recount' (diff)
parentcompletion: collapse extra --no-.. options (diff)
downloadgit-6da2d9595161441cbed1b1f579b8dd46970a8e20.tar.gz
git-6da2d9595161441cbed1b1f579b8dd46970a8e20.zip
Merge branch 'nd/completion-negation'
Continuing with the idea to programmatically enumerate various pieces of data required for command line completion, the codebase has been taught to enumerate options prefixed with "--no-" to negate them. * nd/completion-negation: completion: collapse extra --no-.. options completion: suppress some -no- options parse-options: option to let --git-completion-helper show negative form
Diffstat (limited to 'parse-options.c')
-rw-r--r--parse-options.c58
1 files changed, 54 insertions, 4 deletions
diff --git a/parse-options.c b/parse-options.c
index 0f7059a8ab..7db84227ab 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -427,13 +427,59 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
parse_options_check(options);
}
-/*
- * TODO: we are not completing the --no-XXX form yet because there are
- * many options that do not suppress it properly.
- */
+static void show_negated_gitcomp(const struct option *opts, int nr_noopts)
+{
+ int printed_dashdash = 0;
+
+ for (; opts->type != OPTION_END; opts++) {
+ int has_unset_form = 0;
+ const char *name;
+
+ if (!opts->long_name)
+ continue;
+ if (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE))
+ continue;
+ if (opts->flags & PARSE_OPT_NONEG)
+ continue;
+
+ switch (opts->type) {
+ case OPTION_STRING:
+ case OPTION_FILENAME:
+ case OPTION_INTEGER:
+ case OPTION_MAGNITUDE:
+ case OPTION_CALLBACK:
+ case OPTION_BIT:
+ case OPTION_NEGBIT:
+ case OPTION_COUNTUP:
+ case OPTION_SET_INT:
+ has_unset_form = 1;
+ break;
+ default:
+ break;
+ }
+ if (!has_unset_form)
+ continue;
+
+ if (skip_prefix(opts->long_name, "no-", &name)) {
+ 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++;
+ }
+ }
+}
+
static int show_gitcomp(struct parse_opt_ctx_t *ctx,
const struct option *opts)
{
+ const struct option *original_opts = opts;
+ int nr_noopts = 0;
+
for (; opts->type != OPTION_END; opts++) {
const char *suffix = "";
@@ -463,8 +509,12 @@ static int show_gitcomp(struct parse_opt_ctx_t *ctx,
}
if (opts->flags & PARSE_OPT_COMP_ARG)
suffix = "=";
+ if (starts_with(opts->long_name, "no-"))
+ nr_noopts++;
printf(" --%s%s", opts->long_name, suffix);
}
+ show_negated_gitcomp(original_opts, -1);
+ show_negated_gitcomp(original_opts, nr_noopts);
fputc('\n', stdout);
exit(0);
}