Open dandavison opened 2 years ago
Please note that I have updated my original submission above so that it now contains the clap debug output.
Which behavior did you have with clap2?
What is happening is we have logic to guess when we overflow and should switch to next-line-help for more space. It seems to bail out if the argument column (--merge-conflict-theirs-diff-header-style <STYLE_STRING>
) is larger than the terminal (what is happening before your change). With your change, we are no longer bailing out and clap is thinking it will fit best if we move everything to the following line.
Various forms of this logic have dated back to at least 2017 (so before clap3 though clap3 made slight tweaks around it) and I've still not seen any code reference why we have that bail out or what all use cases we are concerned about for why we are not exclusively staying to one line (ie why we are out guessing the developer).
Hi @epage, thanks for the reply!
Which behavior did you have with clap2?
Delta has just migrated from StructOpt to clap v3, retaining the derive macro / StructOpt style.
I think my core request is this: is it possible to make it so that the -h
output will always be formatted with one line per option, regardless of terminal width etc?
delta has 100 command line options. With one-line-per-option the -h
output is 111 lines, but with multi-line it is 321. So I'm really hoping to be able to give users the "concise" (!) 111 line version with -h
. I'm aware that other clap apps such as bat and ripgrep achieve this (but with clap2, and not using the derive macro StructOpt style).
bail out if the argument column (
--merge-conflict-theirs-diff-header-style <STYLE_STRING>
) is larger than the terminal
I don't think I yet understand the dependence on terminal size that you're referring to -- I have not yet been able to make clap switch between the two formats by changing my terminal width or font size (i.e. causing the output of echo $COLUMNS
and tput cols
to vary). But I might be being slow here! So this is tangential -- my main question is the one above.
Incidentally, the migration to clap has definitely been an improvement to delta, for example because it allowed us to use after_long_help
thus keeping the -h
output minimal. And it was very easy to switch, so thanks to StructOpt and Clap developers for combining them so well -- this is the only issue I've encountered.
I think my core request is this: is it possible to make it so that the -h output will always be formatted with one line per option, regardless of terminal width etc?
delta has 100 command line options. With one-line-per-option the -h output is 111 lines, but with multi-line it is 321. So I'm really hoping to be able to give users the "concise" (!) 111 line version with -h. I'm aware that other clap apps such as bat and ripgrep achieve this (but with clap2, and not using the derive macro StructOpt style).
We only auto-detect terminal size when the wrap_help
feature flag is enabled (seems like an odd name). Otherwise, we rely on the configured App::terminal_width, defaulting to 100 if unset.
You could set App::terminal._width(0)
which means "no wrap" though that will also impact --help
.
In the future, we are looking at opening up our help generation so users can get greater control (https://github.com/clap-rs/clap/issues/2914).
We can leave this issue open though for brainstorming how to improve things in this specific case. I am hesitant to add yet another setting to toggle behavior as API bloat is a current problem with clap. I am more open to ideas that would generally improve the existing behavior or if there are solid enough justifications for dramatic changes. With that said, one thing we can explore is changing from a bool (next line or auto) to a enum (next line, no next line, auto).
I was pointed to this issue from #4409. I have an application where we want help to wrap at 80 characters (since that's the width of a terminal :stuck_out_tongue:) but would like to keep the compact single-line format for short help. This has required us to aggressively limit the lengths of short help strings (we have a CI check for it) because if any one option overruns its line, the entire section gets converted to multi-line format. For some options it'd be nice to have room for a few more words without bloating the rest of the help.
I'd love for clap to be able to wrap individual help texts to a second line within their column. This would allow longer texts to degrade gracefully. So, instead of this:
Options:
--process-integer <INTEGER>
Process an integer with really complex semantics
--process-string <STRING>
Process a string
-h, --help
Print help information
we'd get this:
Options:
--process-integer <INTEGER> Process an integer with really complex
semantics
--process-string <STRING> Process a string
-h, --help Print help information
Presumably that'd need to be configurable, and I understand the hesitation to add more options. I think it'd really improve readability, though.
I'd love for clap to be able to wrap individual help texts to a second line within their column. This would allow longer texts to degrade gracefully. So, instead of this:
clap does that today.
From cargo check
on my machine:
-Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for
details
The problem, and what this issue is about, is our heuristic for switching to next line help.
// force_next_line
let h = arg.get_help().unwrap_or_default();
let h_w = h.display_width() + display_width(spec_vals);
let taken = longest + 12;
self.term_w >= taken
&& (taken as f32 / self.term_w as f32) > 0.40
&& h_w > (self.term_w - taken)
The 40% check is the one that prevents us from always switching to next-line help. I assume the intent is to ensure that the second column is not too small to be very readable. @bgilbert any thoughts on how to balance avoiding next_line_help with the second column being too narrow?
I am noticing a magic number in here. That was most likely missed when we changed the tab width and is likely too large.
Oof, okay. To my mind, next-line help is a last resort, so I'd probably set the limit around 60%. On an 80-column screen that leaves 32 columns, which is a bit narrow but still readable. But, 55% or even 50% would still be an improvement.
I'd also be completely happy with an option to disable (or, I suppose, force) next-line help.
This got me curious about the origin of auto-next-line-help
next_line_help
for short-helpArg::next_line_help(true)
will force the entire section to use next_line_help
(without help_heading
, this basically means all args now that unified help is used). This seems like a bug and it goes against the documentationIn general, I've been wondering if absolute weighting might be better than relative (if the arg is too many characters or the about has too few characters). This then becomes a fairly easy calculation that callers can do to pass in Arg::next_line_help
or Command::next_line_help
and get the behavior they want. Moving this to callers would allow clap to shrink a little bit. The question is how much and if this automation pulls its weight enough to be worth it.
So a part of me leans towards removing all of these calculations (and making Arg::next_line_help
only apply to the one arg) but I would be interested in hearing your thoughts @joshtriplett as the original filer.
Please complete the following tasks
Rust Version
rustc 1.58.0 (02072b482 2022-01-11)
Clap Version
clap = { version = "3.0.5", features = ["derive"] }
Minimal reproducible code
I'm sorry, I have not been able to identify a small example yet. But I do have a reproducible example:
Steps to reproduce the bug with the above code
Run the shell script provided above.
Actual Behaviour
When I run the above shell script, I get the following output:
Expected Behaviour
I expect
delta -h
to always produce help text formatted as one-line-per-option.I think that the code change made in the shell script should not cause clap to change its behavior from one-line-per-option formatting to multple-lines-per-option.
Additional Context
No response
Debug Output