Skip to content

Commit a9baccc

Browse files
avargitster
authored andcommitted
help / completion: make "git help" do the hard work
The "help" builtin has been able to emit configuration variables since e17ca92 (completion: drop the hard coded list of config vars, 2018-05-26), but it hasn't produced exactly the format the completion script wanted. Let's do that. We got partway there in 2675ea1 (completion: use 'sort -u' to deduplicate config variable names, 2019-08-13) and d943887 (completion: deduplicate configuration sections, 2019-08-13), but after both we still needed some sorting, de-duplicating and awk post-processing of the list. We can instead simply do the relevant parsing ourselves (we were doing most of it already), and call string_list_remove_duplicates() after already sorting the list, so the caller doesn't need to invoke "sort -u". The "--config-for-completion" output is the same as before after being passed through "sort -u". Then add a new "--config-sections-for-completion" option. Under that output we'll emit config sections like "alias" (instead of "alias." in the --config-for-completion output). We need to be careful to leave the "--config-for-completion" option compatible with users git, but are still running a shell with an older git-completion.bash. If we e.g. changed the option name they'd see messages about git-completion.bash being unable to find the "--config-for-completion" option. Such backwards compatibility isn't something we should bend over backwards for, it's only helping users who: * Upgrade git * Are in an old shell * The git-completion.bash in that shell hasn't cached the old "--config-for-completion" output already. But since it's easy in this case to retain compatibility, let's do it, the older versions of git-completion.bash won't care that the input they get doesn't change after a "sort -u". While we're at it let's make "--config-for-completion" die if there's anything left over in "argc", and do the same in the new "--config-sections-for-completion" option. Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5a5f04d commit a9baccc

File tree

3 files changed

+65
-27
lines changed

3 files changed

+65
-27
lines changed

builtin/help.c

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,18 @@ enum help_format {
3434
HELP_FORMAT_WEB
3535
};
3636

37+
enum show_config_type {
38+
SHOW_CONFIG_HUMAN,
39+
SHOW_CONFIG_VARS,
40+
SHOW_CONFIG_SECTIONS,
41+
};
42+
3743
static enum help_action {
3844
HELP_ACTION_ALL = 1,
3945
HELP_ACTION_GUIDES,
4046
HELP_ACTION_CONFIG,
4147
HELP_ACTION_CONFIG_FOR_COMPLETION,
48+
HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION,
4249
} cmd_mode;
4350

4451
static const char *html_path;
@@ -63,6 +70,8 @@ static struct option builtin_help_options[] = {
6370
HELP_ACTION_CONFIG),
6471
OPT_CMDMODE_F(0, "config-for-completion", &cmd_mode, "",
6572
HELP_ACTION_CONFIG_FOR_COMPLETION, PARSE_OPT_HIDDEN),
73+
OPT_CMDMODE_F(0, "config-sections-for-completion", &cmd_mode, "",
74+
HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION, PARSE_OPT_HIDDEN),
6675

6776
OPT_END(),
6877
};
@@ -82,7 +91,7 @@ struct slot_expansion {
8291
int found;
8392
};
8493

85-
static void list_config_help(int for_human)
94+
static void list_config_help(enum show_config_type type)
8695
{
8796
struct slot_expansion slot_expansions[] = {
8897
{ "advice", "*", list_config_advices },
@@ -100,6 +109,8 @@ static void list_config_help(int for_human)
100109
const char **p;
101110
struct slot_expansion *e;
102111
struct string_list keys = STRING_LIST_INIT_DUP;
112+
struct string_list keys_uniq = STRING_LIST_INIT_DUP;
113+
struct string_list_item *item;
103114
int i;
104115

105116
for (p = config_name_list; *p; p++) {
@@ -130,34 +141,46 @@ static void list_config_help(int for_human)
130141
for (i = 0; i < keys.nr; i++) {
131142
const char *var = keys.items[i].string;
132143
const char *wildcard, *tag, *cut;
144+
const char *dot = NULL;
145+
struct strbuf sb = STRBUF_INIT;
133146

134-
if (for_human) {
147+
switch (type) {
148+
case SHOW_CONFIG_HUMAN:
135149
puts(var);
136150
continue;
151+
case SHOW_CONFIG_SECTIONS:
152+
dot = strchr(var, '.');
153+
break;
154+
case SHOW_CONFIG_VARS:
155+
break;
137156
}
138-
139157
wildcard = strchr(var, '*');
140158
tag = strchr(var, '<');
141159

142-
if (!wildcard && !tag) {
143-
puts(var);
160+
if (!dot && !wildcard && !tag) {
161+
string_list_append(&keys_uniq, var);
144162
continue;
145163
}
146164

147-
if (wildcard && !tag)
165+
if (dot)
166+
cut = dot;
167+
else if (wildcard && !tag)
148168
cut = wildcard;
149169
else if (!wildcard && tag)
150170
cut = tag;
151171
else
152172
cut = wildcard < tag ? wildcard : tag;
153173

154-
/*
155-
* We may produce duplicates, but that's up to
156-
* git-completion.bash to handle
157-
*/
158-
printf("%.*s\n", (int)(cut - var), var);
174+
strbuf_add(&sb, var, cut - var);
175+
string_list_append(&keys_uniq, sb.buf);
176+
strbuf_release(&sb);
177+
159178
}
160179
string_list_clear(&keys, 0);
180+
string_list_remove_duplicates(&keys_uniq, 0);
181+
for_each_string_list_item(item, &keys_uniq)
182+
puts(item->string);
183+
string_list_clear(&keys_uniq, 0);
161184
}
162185

163186
static enum help_format parse_help_format(const char *format)
@@ -589,12 +612,17 @@ int cmd_help(int argc, const char **argv, const char *prefix)
589612
printf("%s\n", _(git_more_info_string));
590613
return 0;
591614
case HELP_ACTION_CONFIG_FOR_COMPLETION:
592-
list_config_help(0);
615+
no_extra_argc(argc);
616+
list_config_help(SHOW_CONFIG_VARS);
617+
return 0;
618+
case HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION:
619+
no_extra_argc(argc);
620+
list_config_help(SHOW_CONFIG_SECTIONS);
593621
return 0;
594622
case HELP_ACTION_CONFIG:
595623
no_extra_argc(argc);
596624
setup_pager();
597-
list_config_help(1);
625+
list_config_help(SHOW_CONFIG_HUMAN);
598626
printf("\n%s\n", _("'git help config' for more information"));
599627
return 0;
600628
}

contrib/completion/git-completion.bash

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2503,7 +2503,14 @@ __git_config_vars=
25032503
__git_compute_config_vars ()
25042504
{
25052505
test -n "$__git_config_vars" ||
2506-
__git_config_vars="$(git help --config-for-completion | sort -u)"
2506+
__git_config_vars="$(git help --config-for-completion)"
2507+
}
2508+
2509+
__git_config_sections=
2510+
__git_compute_config_sections ()
2511+
{
2512+
test -n "$__git_config_sections" ||
2513+
__git_config_sections="$(git help --config-sections-for-completion)"
25072514
}
25082515

25092516
# Completes possible values of various configuration variables.
@@ -2717,16 +2724,8 @@ __git_complete_config_variable_name ()
27172724
__gitcomp "$__git_config_vars" "" "$cur_" "$sfx"
27182725
;;
27192726
*)
2720-
__git_compute_config_vars
2721-
__gitcomp "$(echo "$__git_config_vars" |
2722-
awk -F . '{
2723-
sections[$1] = 1
2724-
}
2725-
END {
2726-
for (s in sections)
2727-
print s "."
2728-
}
2729-
')" "" "$cur_"
2727+
__git_compute_config_sections
2728+
__gitcomp "$__git_config_sections" "" "$cur_" "."
27302729
;;
27312730
esac
27322731
}

t/t0012-help.sh

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ test_expect_success 'invalid usage' '
4242
test_expect_code 129 git help -a -g &&
4343
4444
test_expect_code 129 git help -g -c &&
45-
test_expect_code 0 git help --config-for-completion add
45+
test_expect_code 129 git help --config-for-completion add &&
46+
test_expect_code 129 git help --config-sections-for-completion add
4647
'
4748

4849
test_expect_success "works for commands and guides by default" '
@@ -106,11 +107,21 @@ test_expect_success 'git help --config-for-completion' '
106107
sort -u >human.munged &&
107108
108109
git help --config-for-completion >vars &&
109-
sort -u <vars >vars.new &&
110-
mv vars.new vars &&
111110
test_cmp human.munged vars
112111
'
113112

113+
test_expect_success 'git help --config-sections-for-completion' '
114+
git help -c >human &&
115+
grep -E \
116+
-e "^[^.]+\.[^.]+$" \
117+
-e "^[^.]+\.[^.]+\.[^.]+$" human |
118+
sed -e "s/\..*//" |
119+
sort -u >human.munged &&
120+
121+
git help --config-sections-for-completion >sections &&
122+
test_cmp human.munged sections
123+
'
124+
114125
test_expect_success 'generate builtin list' '
115126
git --list-cmds=builtins >builtins
116127
'

0 commit comments

Comments
 (0)