Format control over bpaf footer?
VorpalBlade opened this issue · 9 comments
I cannot for the life of be figure out how to control newlines in the footer of --help
output. What I'm trying to achieve is something like:
[...]
-t, --style=STYLE Style of generated modify script [path, path-tmpl (default), src]
[...]
-h, --help Prints help information
-V, --version Prints version information
The --style flag controls how the script that --add generates looks:
* path: chezmoi_modify_manager is searched for in PATH
(modify_ script is not templated for best performance)
* path-tmpl: chezmoi_modify_manager is searched for in PATH
(modify_ script is templated for your convenience)
* src: Program is in .utils of chezmoi source state
(modify_ script is always templated)
However the best I have managed so far is:
The --style flag controls how the script that --add generates looks:
* path: chezmoi_modify_manager is searched for in PATH (modify_ script is not templated for best performance)
* path-tmpl: chezmoi_modify_manager is searched for in PATH (modify_ script is templated for your convenience)
* src: Program is in .utils of chezmoi source state (modify_ script is always templated)
This was done using the following code:
// Extra traits from strum
#[derive(
Debug, Eq, PartialEq, EnumString, Clone, Copy, EnumIter, EnumMessage, Display, IntoStaticStr,
)]
pub enum Style {
/// chezmoi_modify_manager is searched for in PATH (modify_ script is not templated for best performance)
#[strum(serialize = "path")]
InPath,
/// chezmoi_modify_manager is searched for in PATH (modify_ script is templated for your convenience)
#[strum(serialize = "path-tmpl")]
InPathTmpl,
/// Program is in .utils of chezmoi source state (modify_ script is always templated)
#[strum(serialize = "src")]
InSrc,
}
struct StyleFooter();
impl From<StyleFooter> for bpaf::Doc {
fn from(_value: StyleFooter) -> Self {
let mut doc = Self::default();
doc.text("The --style flag controls how the script that --add generates looks:\n");
for s in Style::iter()
{
doc.text(&format!(" * {}: {}\n", s, s.get_documentation().unwrap()));
}
doc
}
}
pub fn parse_args() -> ChmmArgs {
chmm_args()
.footer(StyleFooter())
.run()
}
If I change to add in the extra newlines, bpaf just eats half my output:
The --style flag controls how the script that --add generates looks:
* path: chezmoi_modify_manager is searched for in PATH (modify_ script is not templated for best performance)
(the rest is missing)
If I don't really care about generating markdown or man pages, is there a "do as I say" escape hatch?
(Oh another thing, I thought if I passed something that was Into<Doc>
it would lazily evaluated only if the help text is produced. This is not the case unfortunately it seems after reading the code.
Since I'm working on optimising the runtime as much as possible for my program (and total runtime for a single invocation is 1-2 ms, but it is typically called many times by another program) I might look for an alternative solution, such as just providing a link to online docs, or a custom written man page.
Though if the formatting issue can be solved it doesn't seem like the overhead of doing this eagerly is actually very much currently when I check with hyperfine.)
This should help with forcing linebreaks
pub enum Style {
/// chezmoi_modify_manager is searched for in PATH
/// (modify_ script is not templated for best performance) // <- note extra space
#[strum(serialize = "path")]
InPath,
}
There's no escape hatches other than that.
For style - this is mostly useful if you want to use different styles - bold/emphasis, etc. Just to get line breaks you should be able to use line that starts with a single space. If you pass static str - it should have no extra runtime cost.
As for performance - I don't think I did any measurements, just making sure I'm not doing anything stupid, I guess I'll take a look.
Hm, doesn't markdown support having a trailing \
instead of a space? I tried that, but it didn't work. I have my editor set to strip trailing WS in all my projects, so I really don't like that one.
/// (modify_ script is not templated for best performance)
^--- I was talking about this space :)
Aha! Thanks.
I got a good enough output now, but the trick with leading spaces should probably be documented somewhere on https://docs.rs/bpaf/latest/bpaf/struct.Doc.html
For combinatoric API it's .help("hello\n word")
<- space at the beginning of the line.
but the trick with leading spaces should probably be documented somewhere
My bad. It is documented in a few other places, I was sure I mentioned it there too... Will fix.
I documented it in most of the places that existed before Doc
, like here:
https://docs.rs/bpaf/latest/bpaf/params/struct.NamedArg.html#method.help
Doc
is a recent addition...
Yes, the issue with docs.rs for bpaf (and other large crates) is that the search function isn't full-text from what I can tell. It only finds types/symbols/etc. So it is very hard to find these (or search in the tutorial pages etc)