short help: allow multi-line opthelp

When "-h" triggers the short-help in a command that implements its option parsing using the parse-options API, the option help text is shown with a single fprintf() as a long line. When the text is multi-line, the second and subsequent lines are not left padded, that breaks the alignment across options. Borrowing the idea from the advice API where its hint strings are shown with (localized) "hint:" prefix, let's internally split the (localized) help text into lines, and showing the first line, pad the remaining lines to align. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Jul 18, 2023 at 15:54 UTC 448abbba63471153df6ba520a5621595557ce3c8
3 files changed +15 -1
parse-options.c
+11 -1
@@ -1109,6 +1109,7 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t
1109 for (; opts->type != OPTION_END; opts++) {
1110 size_t pos;
1111 int pad;
1112 + const char *cp, *np;
1113
1114 if (opts->type == OPTION_SUBCOMMAND)
1115 continue;
@@ -1157,7 +1158,16 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t
1158 (const char *)opts->value);
1159 continue;
1160 }
1160 - fprintf(outfile, "%*s%s\n", pad + USAGE_GAP, "", _(opts->help));
1161 +
1162 + for (cp = _(opts->help); *cp; cp = np) {
1163 + np = strchrnul(cp, '\n');
1164 + fprintf(outfile,
1165 + "%*s%.*s\n", pad + USAGE_GAP, "",
1166 + (int)(np - cp), cp);
1167 + if (*np)
1168 + np++;
1169 + pad = USAGE_OPTS_WIDTH;
1170 + }
1171 }
1172 fputc('\n', outfile);
1173
t/helper/test-parse-options.c
+2
@@ -133,6 +133,8 @@ int cmd__parse_options(int argc, const char **argv)
133 OPT_STRING(0, "st", &string, "st", "get another string (pervert ordering)"),
134 OPT_STRING('o', NULL, &string, "str", "get another string"),
135 OPT_NOOP_NOARG(0, "obsolete"),
136 + OPT_SET_INT_F(0, "longhelp", &integer, "help text of this entry\n"
137 + "spans multiple lines", 0, PARSE_OPT_NONEG),
138 OPT_STRING_LIST(0, "list", &list, "str", "add str to list"),
139 OPT_GROUP("Magic arguments"),
140 OPT_NUMBER_CALLBACK(&integer, "set integer to NUM",
t/t0040-parse-options.sh
+2
@@ -35,6 +35,8 @@ String options
35 --string2 <str> get another string
36 --st <st> get another string (pervert ordering)
37 -o <str> get another string
38 + --longhelp help text of this entry
39 + spans multiple lines
40 --list <str> add str to list
41
42 Magic arguments