Skip to content

Commit b9d7f4b

Browse files
pcloudsgitster
authored andcommitted
parse-options: support --git-completion-helper
This option is designed to be used by git-completion.bash. For many simple cases, what we do in there is usually __gitcomp "lots of completion options" which has to be manually updated when a new user-visible option is added. With support from parse-options, we can write __gitcomp "$(git command --git-completion-helper)" and get that list directly from the parser for free. Dangerous/Unpopular options could be hidden with the new "NOCOMPLETE" flag. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 5be1f00 commit b9d7f4b

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

parse-options.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,46 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
425425
parse_options_check(options);
426426
}
427427

428+
/*
429+
* TODO: we are not completing the --no-XXX form yet because there are
430+
* many options that do not suppress it properly.
431+
*/
432+
static int show_gitcomp(struct parse_opt_ctx_t *ctx,
433+
const struct option *opts)
434+
{
435+
for (; opts->type != OPTION_END; opts++) {
436+
const char *suffix = "";
437+
438+
if (!opts->long_name)
439+
continue;
440+
if (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE))
441+
continue;
442+
443+
switch (opts->type) {
444+
case OPTION_GROUP:
445+
continue;
446+
case OPTION_STRING:
447+
case OPTION_FILENAME:
448+
case OPTION_INTEGER:
449+
case OPTION_MAGNITUDE:
450+
case OPTION_CALLBACK:
451+
if (opts->flags & PARSE_OPT_NOARG)
452+
break;
453+
if (opts->flags & PARSE_OPT_OPTARG)
454+
break;
455+
if (opts->flags & PARSE_OPT_LASTARG_DEFAULT)
456+
break;
457+
suffix = "=";
458+
break;
459+
default:
460+
break;
461+
}
462+
printf(" --%s%s", opts->long_name, suffix);
463+
}
464+
fputc('\n', stdout);
465+
exit(0);
466+
}
467+
428468
static int usage_with_options_internal(struct parse_opt_ctx_t *,
429469
const char * const *,
430470
const struct option *, int, int);
@@ -455,6 +495,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
455495
if (internal_help && ctx->total == 1 && !strcmp(arg + 1, "h"))
456496
goto show_usage;
457497

498+
/* lone --git-completion-helper is asked by git-completion.bash */
499+
if (ctx->total == 1 && !strcmp(arg + 1, "-git-completion-helper"))
500+
return show_gitcomp(ctx, options);
501+
458502
if (arg[1] != '-') {
459503
ctx->opt = arg + 1;
460504
switch (parse_short_opt(ctx, options)) {

parse-options.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ enum parse_opt_option_flags {
3838
PARSE_OPT_LASTARG_DEFAULT = 16,
3939
PARSE_OPT_NODASH = 32,
4040
PARSE_OPT_LITERAL_ARGHELP = 64,
41-
PARSE_OPT_SHELL_EVAL = 256
41+
PARSE_OPT_SHELL_EVAL = 256,
42+
PARSE_OPT_NOCOMPLETE = 512
4243
};
4344

4445
struct option;
@@ -89,6 +90,8 @@ typedef int parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
8990
* PARSE_OPT_LITERAL_ARGHELP: says that argh shouldn't be enclosed in brackets
9091
* (i.e. '<argh>') in the help message.
9192
* Useful for options with multiple parameters.
93+
* PARSE_OPT_NOCOMPLETE: by default all visible options are completable
94+
* by git-completion.bash. This option suppresses that.
9295
*
9396
* `callback`::
9497
* pointer to the callback to use for OPTION_CALLBACK or

0 commit comments

Comments
 (0)