Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Format control over bpaf footer? #339

Open
Tracked by #406
VorpalBlade opened this issue Jan 27, 2024 · 9 comments
Open
Tracked by #406

Format control over bpaf footer? #339

VorpalBlade opened this issue Jan 27, 2024 · 9 comments

Comments

@VorpalBlade
Copy link

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?

@VorpalBlade
Copy link
Author

VorpalBlade commented Jan 27, 2024

(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.)

@pacak
Copy link
Owner

pacak commented Jan 27, 2024

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.

@VorpalBlade
Copy link
Author

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.

@pacak
Copy link
Owner

pacak commented Jan 27, 2024

///  (modify_ script is not templated for best performance)
    ^--- I was talking about this space :)

@VorpalBlade
Copy link
Author

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

@pacak
Copy link
Owner

pacak commented Jan 27, 2024

For combinatoric API it's .help("hello\n word") <- space at the beginning of the line.

@pacak
Copy link
Owner

pacak commented Jan 27, 2024

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.

@pacak
Copy link
Owner

pacak commented Jan 27, 2024

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...

@VorpalBlade
Copy link
Author

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)

@pacak pacak mentioned this issue Jan 1, 2025
21 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants