Skip to content

Commit 40efc70

Browse files
committed
formatter: add long_option_alignment_ratio
The default formatter has hardcoded ratio at which the long options are aligned. It's currently 1/3 of the column, which makes the default look awkward: -h, --help Print --option Something A ->long_option_alignment_ratio(6/30.f) allows output to look like this: -h, --help Print --option Something The 1/3 ratio is also bad if you want to print "descriptive" long options on a single line, because then you might want to increase the column width, but that means you waste more space on short options. e.g. ->column_width(46) -l, --very-descriptive-long-option Something vs. ->column_width(38) -l, --very-descriptive-long-option Something vs. ->column_width(38) ->long_option_alignment_ratio(6/38.f) -l, --very-descriptive-long-option Something Any absolute offset `X` can be set as `X/column_width`, so provide a ratio-based interface. I would have prefered to give an absolute integer offset, but we still have to preserve the functionality that does 1/3 if user changed nothing, which means that ratio-based interface is simpler. I don't have a good idea for the name, "short_option_ratio" might work as well. The setter does not sanity check that the value is in [0;1] range. Signed-off-by: Radim Krčmář <radim@krcmar.dev>
1 parent c515363 commit 40efc70

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

include/CLI/FormatterFwd.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ class FormatterBase {
4747
/// The width of the left column (options/flags/subcommands)
4848
std::size_t column_width_{30};
4949

50+
/// The alignment ratio for long options within the left column
51+
float long_option_alignment_ratio_{1/3.f};
52+
5053
/// The width of the right column (description of options/flags/subcommands)
5154
std::size_t right_column_width_{65};
5255

@@ -91,6 +94,10 @@ class FormatterBase {
9194
/// Set the left column width (options/flags/subcommands)
9295
void column_width(std::size_t val) { column_width_ = val; }
9396

97+
/// Set the alignment ratio for long options within the left column
98+
/// The ratio is in [0;1] range (e.g. 0.2 = 20% of column width, 6.f/column_width = 6th character)
99+
void long_option_alignment_ratio(float ratio) { long_option_alignment_ratio_ = ratio; }
100+
94101
/// Set the right column width (description of options/flags/subcommands)
95102
void right_column_width(std::size_t val) { right_column_width_ = val; }
96103

include/CLI/impl/Formatter_inl.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,9 @@ CLI11_INLINE std::string Formatter::make_option(const Option *opt, bool is_posit
298298
std::string longNames = detail::join(vlongNames, ", ");
299299

300300
// Calculate setw sizes
301-
const auto shortNamesColumnWidth = static_cast<int>(column_width_ / 3); // 33% left for short names
302-
const auto longNamesColumnWidth = static_cast<int>(std::ceil(
303-
static_cast<float>(column_width_) / 3.0f * 2.0f)); // 66% right for long names and options, ceil result
301+
// Short names take enough width to align long names at the desired ratio
302+
const auto shortNamesColumnWidth = static_cast<int>(static_cast<float>(column_width_) * long_option_alignment_ratio_);
303+
const auto longNamesColumnWidth = static_cast<int>(column_width_) - shortNamesColumnWidth;
304304
int shortNamesOverSize = 0;
305305

306306
// Print short names

tests/FormatterTest.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,3 +261,17 @@ TEST_CASE("Formatter: Description", "[formatter]") {
261261
CHECK_THAT(help, !Contains("to Pr e s e r v e SPA C ES"));
262262
CHECK_THAT(help, !Contains(desc_string));
263263
}
264+
265+
TEST_CASE("Formatter: LongOptionAlignment", "[formatter]") {
266+
CLI::App app{"My prog"};
267+
268+
app.get_formatter()->long_option_alignment_ratio(6/30.f);
269+
270+
int v{0};
271+
app.add_option("--opt", v, "Something");
272+
273+
std::string help = app.help();
274+
275+
CHECK_THAT(help, Contains("\n -h, --help Print"));
276+
CHECK_THAT(help, Contains("\n --opt INT Something"));
277+
}

0 commit comments

Comments
 (0)