Merge branch 'ab/help-config-vars'
Teach "git help -c" into helping the command line completion of configuration variables. * ab/help-config-vars: help: move column config discovery to help.c library help / completion: make "git help" do the hard work help tests: test --config-for-completion option & output help: simplify by moving to OPT_CMDMODE() help: correct logic error in combining --all and --guides help: correct logic error in combining --all and --config help tests: add test for --config output help: correct usage & behavior of "git help --guides" help: correct the usage string in -h and documentation
This commit is contained in:
commit
62f035aee3
@ -8,8 +8,10 @@ git-help - Display help information about Git
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git help' [-a|--all [--[no-]verbose]] [-g|--guides]
|
||||
[-i|--info|-m|--man|-w|--web] [COMMAND|GUIDE]
|
||||
'git help' [-a|--all [--[no-]verbose]]
|
||||
[[-i|--info] [-m|--man] [-w|--web]] [COMMAND|GUIDE]
|
||||
'git help' [-g|--guides]
|
||||
'git help' [-c|--config]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@ -58,8 +60,7 @@ OPTIONS
|
||||
|
||||
-g::
|
||||
--guides::
|
||||
Prints a list of the Git concept guides on the standard output. This
|
||||
option overrides any given command or guide name.
|
||||
Prints a list of the Git concept guides on the standard output.
|
||||
|
||||
-i::
|
||||
--info::
|
||||
|
133
builtin/help.c
133
builtin/help.c
@ -7,7 +7,6 @@
|
||||
#include "exec-cmd.h"
|
||||
#include "parse-options.h"
|
||||
#include "run-command.h"
|
||||
#include "column.h"
|
||||
#include "config-list.h"
|
||||
#include "help.h"
|
||||
#include "alias.h"
|
||||
@ -34,32 +33,52 @@ enum help_format {
|
||||
HELP_FORMAT_WEB
|
||||
};
|
||||
|
||||
static const char *html_path;
|
||||
enum show_config_type {
|
||||
SHOW_CONFIG_HUMAN,
|
||||
SHOW_CONFIG_VARS,
|
||||
SHOW_CONFIG_SECTIONS,
|
||||
};
|
||||
|
||||
static int show_all = 0;
|
||||
static int show_guides = 0;
|
||||
static int show_config;
|
||||
static enum help_action {
|
||||
HELP_ACTION_ALL = 1,
|
||||
HELP_ACTION_GUIDES,
|
||||
HELP_ACTION_CONFIG,
|
||||
HELP_ACTION_CONFIG_FOR_COMPLETION,
|
||||
HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION,
|
||||
} cmd_mode;
|
||||
|
||||
static const char *html_path;
|
||||
static int verbose = 1;
|
||||
static unsigned int colopts;
|
||||
static enum help_format help_format = HELP_FORMAT_NONE;
|
||||
static int exclude_guides;
|
||||
static struct option builtin_help_options[] = {
|
||||
OPT_BOOL('a', "all", &show_all, N_("print all available commands")),
|
||||
OPT_CMDMODE('a', "all", &cmd_mode, N_("print all available commands"),
|
||||
HELP_ACTION_ALL),
|
||||
OPT_HIDDEN_BOOL(0, "exclude-guides", &exclude_guides, N_("exclude guides")),
|
||||
OPT_BOOL('g', "guides", &show_guides, N_("print list of useful guides")),
|
||||
OPT_BOOL('c', "config", &show_config, N_("print all configuration variable names")),
|
||||
OPT_SET_INT_F(0, "config-for-completion", &show_config, "", 2, PARSE_OPT_HIDDEN),
|
||||
OPT_SET_INT('m', "man", &help_format, N_("show man page"), HELP_FORMAT_MAN),
|
||||
OPT_SET_INT('w', "web", &help_format, N_("show manual in web browser"),
|
||||
HELP_FORMAT_WEB),
|
||||
OPT_SET_INT('i', "info", &help_format, N_("show info page"),
|
||||
HELP_FORMAT_INFO),
|
||||
OPT__VERBOSE(&verbose, N_("print command description")),
|
||||
|
||||
OPT_CMDMODE('g', "guides", &cmd_mode, N_("print list of useful guides"),
|
||||
HELP_ACTION_GUIDES),
|
||||
OPT_CMDMODE('c', "config", &cmd_mode, N_("print all configuration variable names"),
|
||||
HELP_ACTION_CONFIG),
|
||||
OPT_CMDMODE_F(0, "config-for-completion", &cmd_mode, "",
|
||||
HELP_ACTION_CONFIG_FOR_COMPLETION, PARSE_OPT_HIDDEN),
|
||||
OPT_CMDMODE_F(0, "config-sections-for-completion", &cmd_mode, "",
|
||||
HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION, PARSE_OPT_HIDDEN),
|
||||
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
static const char * const builtin_help_usage[] = {
|
||||
N_("git help [--all] [--guides] [--man | --web | --info] [<command>]"),
|
||||
N_("git help [-a|--all] [--[no-]verbose]]\n"
|
||||
" [[-i|--info] [-m|--man] [-w|--web]] [<command>]"),
|
||||
N_("git help [-g|--guides]"),
|
||||
N_("git help [-c|--config]"),
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -70,7 +89,7 @@ struct slot_expansion {
|
||||
int found;
|
||||
};
|
||||
|
||||
static void list_config_help(int for_human)
|
||||
static void list_config_help(enum show_config_type type)
|
||||
{
|
||||
struct slot_expansion slot_expansions[] = {
|
||||
{ "advice", "*", list_config_advices },
|
||||
@ -88,6 +107,8 @@ static void list_config_help(int for_human)
|
||||
const char **p;
|
||||
struct slot_expansion *e;
|
||||
struct string_list keys = STRING_LIST_INIT_DUP;
|
||||
struct string_list keys_uniq = STRING_LIST_INIT_DUP;
|
||||
struct string_list_item *item;
|
||||
int i;
|
||||
|
||||
for (p = config_name_list; *p; p++) {
|
||||
@ -118,34 +139,46 @@ static void list_config_help(int for_human)
|
||||
for (i = 0; i < keys.nr; i++) {
|
||||
const char *var = keys.items[i].string;
|
||||
const char *wildcard, *tag, *cut;
|
||||
const char *dot = NULL;
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
|
||||
if (for_human) {
|
||||
switch (type) {
|
||||
case SHOW_CONFIG_HUMAN:
|
||||
puts(var);
|
||||
continue;
|
||||
case SHOW_CONFIG_SECTIONS:
|
||||
dot = strchr(var, '.');
|
||||
break;
|
||||
case SHOW_CONFIG_VARS:
|
||||
break;
|
||||
}
|
||||
|
||||
wildcard = strchr(var, '*');
|
||||
tag = strchr(var, '<');
|
||||
|
||||
if (!wildcard && !tag) {
|
||||
puts(var);
|
||||
if (!dot && !wildcard && !tag) {
|
||||
string_list_append(&keys_uniq, var);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wildcard && !tag)
|
||||
if (dot)
|
||||
cut = dot;
|
||||
else if (wildcard && !tag)
|
||||
cut = wildcard;
|
||||
else if (!wildcard && tag)
|
||||
cut = tag;
|
||||
else
|
||||
cut = wildcard < tag ? wildcard : tag;
|
||||
|
||||
/*
|
||||
* We may produce duplicates, but that's up to
|
||||
* git-completion.bash to handle
|
||||
*/
|
||||
printf("%.*s\n", (int)(cut - var), var);
|
||||
strbuf_add(&sb, var, cut - var);
|
||||
string_list_append(&keys_uniq, sb.buf);
|
||||
strbuf_release(&sb);
|
||||
|
||||
}
|
||||
string_list_clear(&keys, 0);
|
||||
string_list_remove_duplicates(&keys_uniq, 0);
|
||||
for_each_string_list_item(item, &keys_uniq)
|
||||
puts(item->string);
|
||||
string_list_clear(&keys_uniq, 0);
|
||||
}
|
||||
|
||||
static enum help_format parse_help_format(const char *format)
|
||||
@ -349,8 +382,6 @@ static int add_man_viewer_info(const char *var, const char *value)
|
||||
|
||||
static int git_help_config(const char *var, const char *value, void *cb)
|
||||
{
|
||||
if (starts_with(var, "column."))
|
||||
return git_column_config(var, value, "help", &colopts);
|
||||
if (!strcmp(var, "help.format")) {
|
||||
if (!value)
|
||||
return config_error_nonbool(var);
|
||||
@ -544,6 +575,13 @@ static const char *check_git_cmd(const char* cmd)
|
||||
return cmd;
|
||||
}
|
||||
|
||||
static void no_extra_argc(int argc)
|
||||
{
|
||||
if (argc)
|
||||
usage_msg_opt(_("this option doesn't take any other arguments"),
|
||||
builtin_help_usage, builtin_help_options);
|
||||
}
|
||||
|
||||
int cmd_help(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int nongit;
|
||||
@ -554,8 +592,8 @@ int cmd_help(int argc, const char **argv, const char *prefix)
|
||||
builtin_help_usage, 0);
|
||||
parsed_help_format = help_format;
|
||||
|
||||
if (show_all) {
|
||||
git_config(git_help_config, NULL);
|
||||
switch (cmd_mode) {
|
||||
case HELP_ACTION_ALL:
|
||||
if (verbose) {
|
||||
setup_pager();
|
||||
list_all_cmds_help();
|
||||
@ -563,30 +601,27 @@ int cmd_help(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
printf(_("usage: %s%s"), _(git_usage_string), "\n\n");
|
||||
load_command_list("git-", &main_cmds, &other_cmds);
|
||||
list_commands(colopts, &main_cmds, &other_cmds);
|
||||
}
|
||||
|
||||
if (show_config) {
|
||||
int for_human = show_config == 1;
|
||||
|
||||
if (!for_human) {
|
||||
list_config_help(for_human);
|
||||
return 0;
|
||||
}
|
||||
setup_pager();
|
||||
list_config_help(for_human);
|
||||
printf("\n%s\n", _("'git help config' for more information"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (show_guides)
|
||||
list_guides_help();
|
||||
|
||||
if (show_all || show_guides) {
|
||||
list_commands(&main_cmds, &other_cmds);
|
||||
printf("%s\n", _(git_more_info_string));
|
||||
/*
|
||||
* We're done. Ignore any remaining args
|
||||
*/
|
||||
break;
|
||||
case HELP_ACTION_GUIDES:
|
||||
no_extra_argc(argc);
|
||||
list_guides_help();
|
||||
printf("%s\n", _(git_more_info_string));
|
||||
return 0;
|
||||
case HELP_ACTION_CONFIG_FOR_COMPLETION:
|
||||
no_extra_argc(argc);
|
||||
list_config_help(SHOW_CONFIG_VARS);
|
||||
return 0;
|
||||
case HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION:
|
||||
no_extra_argc(argc);
|
||||
list_config_help(SHOW_CONFIG_SECTIONS);
|
||||
return 0;
|
||||
case HELP_ACTION_CONFIG:
|
||||
no_extra_argc(argc);
|
||||
setup_pager();
|
||||
list_config_help(SHOW_CONFIG_HUMAN);
|
||||
printf("\n%s\n", _("'git help config' for more information"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2503,7 +2503,14 @@ __git_config_vars=
|
||||
__git_compute_config_vars ()
|
||||
{
|
||||
test -n "$__git_config_vars" ||
|
||||
__git_config_vars="$(git help --config-for-completion | sort -u)"
|
||||
__git_config_vars="$(git help --config-for-completion)"
|
||||
}
|
||||
|
||||
__git_config_sections=
|
||||
__git_compute_config_sections ()
|
||||
{
|
||||
test -n "$__git_config_sections" ||
|
||||
__git_config_sections="$(git help --config-sections-for-completion)"
|
||||
}
|
||||
|
||||
# Completes possible values of various configuration variables.
|
||||
@ -2717,16 +2724,8 @@ __git_complete_config_variable_name ()
|
||||
__gitcomp "$__git_config_vars" "" "$cur_" "$sfx"
|
||||
;;
|
||||
*)
|
||||
__git_compute_config_vars
|
||||
__gitcomp "$(echo "$__git_config_vars" |
|
||||
awk -F . '{
|
||||
sections[$1] = 1
|
||||
}
|
||||
END {
|
||||
for (s in sections)
|
||||
print s "."
|
||||
}
|
||||
')" "" "$cur_"
|
||||
__git_compute_config_sections
|
||||
__gitcomp "$__git_config_sections" "" "$cur_" "."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
16
help.c
16
help.c
@ -293,9 +293,21 @@ void load_command_list(const char *prefix,
|
||||
exclude_cmds(other_cmds, main_cmds);
|
||||
}
|
||||
|
||||
void list_commands(unsigned int colopts,
|
||||
struct cmdnames *main_cmds, struct cmdnames *other_cmds)
|
||||
static int get_colopts(const char *var, const char *value, void *data)
|
||||
{
|
||||
unsigned int *colopts = data;
|
||||
|
||||
if (starts_with(var, "column."))
|
||||
return git_column_config(var, value, "help", colopts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void list_commands(struct cmdnames *main_cmds, struct cmdnames *other_cmds)
|
||||
{
|
||||
unsigned int colopts = 0;
|
||||
git_config(get_colopts, &colopts);
|
||||
|
||||
if (main_cmds->cnt) {
|
||||
const char *exec_path = git_exec_path();
|
||||
printf_ln(_("available git commands in '%s'"), exec_path);
|
||||
|
2
help.h
2
help.h
@ -37,7 +37,7 @@ void add_cmdname(struct cmdnames *cmds, const char *name, int len);
|
||||
/* Here we require that excludes is a sorted list. */
|
||||
void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes);
|
||||
int is_in_cmdlist(struct cmdnames *cmds, const char *name);
|
||||
void list_commands(unsigned int colopts, struct cmdnames *main_cmds, struct cmdnames *other_cmds);
|
||||
void list_commands(struct cmdnames *main_cmds, struct cmdnames *other_cmds);
|
||||
void get_version_info(struct strbuf *buf, int show_build_options);
|
||||
|
||||
/*
|
||||
|
@ -166,8 +166,10 @@ struct option {
|
||||
#define OPT_BOOL(s, l, v, h) OPT_BOOL_F(s, l, v, h, 0)
|
||||
#define OPT_HIDDEN_BOOL(s, l, v, h) { OPTION_SET_INT, (s), (l), (v), NULL, \
|
||||
(h), PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1}
|
||||
#define OPT_CMDMODE(s, l, v, h, i) { OPTION_SET_INT, (s), (l), (v), NULL, \
|
||||
(h), PARSE_OPT_CMDMODE|PARSE_OPT_NOARG|PARSE_OPT_NONEG, NULL, (i) }
|
||||
#define OPT_CMDMODE_F(s, l, v, h, i, f) { OPTION_SET_INT, (s), (l), (v), NULL, \
|
||||
(h), PARSE_OPT_CMDMODE|PARSE_OPT_NOARG|PARSE_OPT_NONEG | (f), NULL, (i) }
|
||||
#define OPT_CMDMODE(s, l, v, h, i) OPT_CMDMODE_F(s, l, v, h, i, 0)
|
||||
|
||||
#define OPT_INTEGER(s, l, v, h) OPT_INTEGER_F(s, l, v, h, 0)
|
||||
#define OPT_MAGNITUDE(s, l, v, h) { OPTION_MAGNITUDE, (s), (l), (v), \
|
||||
N_("n"), (h), PARSE_OPT_NONEG }
|
||||
|
@ -34,6 +34,18 @@ test_expect_success 'basic help commands' '
|
||||
git help -a >/dev/null
|
||||
'
|
||||
|
||||
test_expect_success 'invalid usage' '
|
||||
test_expect_code 129 git help -g add &&
|
||||
test_expect_code 129 git help -a -c &&
|
||||
|
||||
test_expect_code 129 git help -g add &&
|
||||
test_expect_code 129 git help -a -g &&
|
||||
|
||||
test_expect_code 129 git help -g -c &&
|
||||
test_expect_code 129 git help --config-for-completion add &&
|
||||
test_expect_code 129 git help --config-sections-for-completion add
|
||||
'
|
||||
|
||||
test_expect_success "works for commands and guides by default" '
|
||||
configure_help &&
|
||||
git help status &&
|
||||
@ -89,6 +101,43 @@ test_expect_success 'git help succeeds without git.html' '
|
||||
test_cmp expect test-browser.log
|
||||
'
|
||||
|
||||
test_expect_success 'git help -c' '
|
||||
git help -c >help.output &&
|
||||
cat >expect <<-\EOF &&
|
||||
|
||||
'\''git help config'\'' for more information
|
||||
EOF
|
||||
grep -v -E \
|
||||
-e "^[^.]+\.[^.]+$" \
|
||||
-e "^[^.]+\.[^.]+\.[^.]+$" \
|
||||
help.output >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'git help --config-for-completion' '
|
||||
git help -c >human &&
|
||||
grep -E \
|
||||
-e "^[^.]+\.[^.]+$" \
|
||||
-e "^[^.]+\.[^.]+\.[^.]+$" human |
|
||||
sed -e "s/\*.*//" -e "s/<.*//" |
|
||||
sort -u >human.munged &&
|
||||
|
||||
git help --config-for-completion >vars &&
|
||||
test_cmp human.munged vars
|
||||
'
|
||||
|
||||
test_expect_success 'git help --config-sections-for-completion' '
|
||||
git help -c >human &&
|
||||
grep -E \
|
||||
-e "^[^.]+\.[^.]+$" \
|
||||
-e "^[^.]+\.[^.]+\.[^.]+$" human |
|
||||
sed -e "s/\..*//" |
|
||||
sort -u >human.munged &&
|
||||
|
||||
git help --config-sections-for-completion >sections &&
|
||||
test_cmp human.munged sections
|
||||
'
|
||||
|
||||
test_expect_success 'generate builtin list' '
|
||||
git --list-cmds=builtins >builtins
|
||||
'
|
||||
|
Loading…
Reference in New Issue
Block a user