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>
This commit is contained in:
parent
5be1f00a9a
commit
b9d7f4b4db
@ -425,6 +425,46 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
|
|||||||
parse_options_check(options);
|
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 int show_gitcomp(struct parse_opt_ctx_t *ctx,
|
||||||
|
const struct option *opts)
|
||||||
|
{
|
||||||
|
for (; opts->type != OPTION_END; opts++) {
|
||||||
|
const char *suffix = "";
|
||||||
|
|
||||||
|
if (!opts->long_name)
|
||||||
|
continue;
|
||||||
|
if (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (opts->type) {
|
||||||
|
case OPTION_GROUP:
|
||||||
|
continue;
|
||||||
|
case OPTION_STRING:
|
||||||
|
case OPTION_FILENAME:
|
||||||
|
case OPTION_INTEGER:
|
||||||
|
case OPTION_MAGNITUDE:
|
||||||
|
case OPTION_CALLBACK:
|
||||||
|
if (opts->flags & PARSE_OPT_NOARG)
|
||||||
|
break;
|
||||||
|
if (opts->flags & PARSE_OPT_OPTARG)
|
||||||
|
break;
|
||||||
|
if (opts->flags & PARSE_OPT_LASTARG_DEFAULT)
|
||||||
|
break;
|
||||||
|
suffix = "=";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf(" --%s%s", opts->long_name, suffix);
|
||||||
|
}
|
||||||
|
fputc('\n', stdout);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
static int usage_with_options_internal(struct parse_opt_ctx_t *,
|
static int usage_with_options_internal(struct parse_opt_ctx_t *,
|
||||||
const char * const *,
|
const char * const *,
|
||||||
const struct option *, int, int);
|
const struct option *, int, int);
|
||||||
@ -455,6 +495,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
|
|||||||
if (internal_help && ctx->total == 1 && !strcmp(arg + 1, "h"))
|
if (internal_help && ctx->total == 1 && !strcmp(arg + 1, "h"))
|
||||||
goto show_usage;
|
goto show_usage;
|
||||||
|
|
||||||
|
/* lone --git-completion-helper is asked by git-completion.bash */
|
||||||
|
if (ctx->total == 1 && !strcmp(arg + 1, "-git-completion-helper"))
|
||||||
|
return show_gitcomp(ctx, options);
|
||||||
|
|
||||||
if (arg[1] != '-') {
|
if (arg[1] != '-') {
|
||||||
ctx->opt = arg + 1;
|
ctx->opt = arg + 1;
|
||||||
switch (parse_short_opt(ctx, options)) {
|
switch (parse_short_opt(ctx, options)) {
|
||||||
|
@ -38,7 +38,8 @@ enum parse_opt_option_flags {
|
|||||||
PARSE_OPT_LASTARG_DEFAULT = 16,
|
PARSE_OPT_LASTARG_DEFAULT = 16,
|
||||||
PARSE_OPT_NODASH = 32,
|
PARSE_OPT_NODASH = 32,
|
||||||
PARSE_OPT_LITERAL_ARGHELP = 64,
|
PARSE_OPT_LITERAL_ARGHELP = 64,
|
||||||
PARSE_OPT_SHELL_EVAL = 256
|
PARSE_OPT_SHELL_EVAL = 256,
|
||||||
|
PARSE_OPT_NOCOMPLETE = 512
|
||||||
};
|
};
|
||||||
|
|
||||||
struct option;
|
struct option;
|
||||||
@ -89,6 +90,8 @@ typedef int parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
|
|||||||
* PARSE_OPT_LITERAL_ARGHELP: says that argh shouldn't be enclosed in brackets
|
* PARSE_OPT_LITERAL_ARGHELP: says that argh shouldn't be enclosed in brackets
|
||||||
* (i.e. '<argh>') in the help message.
|
* (i.e. '<argh>') in the help message.
|
||||||
* Useful for options with multiple parameters.
|
* Useful for options with multiple parameters.
|
||||||
|
* PARSE_OPT_NOCOMPLETE: by default all visible options are completable
|
||||||
|
* by git-completion.bash. This option suppresses that.
|
||||||
*
|
*
|
||||||
* `callback`::
|
* `callback`::
|
||||||
* pointer to the callback to use for OPTION_CALLBACK or
|
* pointer to the callback to use for OPTION_CALLBACK or
|
||||||
|
Loading…
x
Reference in New Issue
Block a user