Open ghost opened 1 year ago
Sorry this isn't possible right now.
Ah that is too bad!
Before optparse-applicative, our help looked like this:
but now, with optparse, it looks like this:
It is not terrible, but we had titles for the groups of commands bold, and commands where yellowish, and we would like to keep those styles.
Are there any considerations to add this in the future? If we wanted to make a PR for it ourselves, could you recommend a place where to start, the direction?
Yeah.
So one of the things I'm considering is adding semantic annotations to the pretty printer document which are then compiled to ANSI codes.
Thanks for sharing.
Just a hint, the extra (Command | Command) can be fixed with hidden on one of them.
Yeah.
So one of the things I'm considering is adding semantic annotations to the pretty printer document which are then compiled to ANSI codes.
Thanks for sharing.
That sounds interesting.
I was hoping there would be some easy way to provide our own logic for "styling" the help output. For example, I could provide a function that takes subgroup name as an input and returns it stylized (well, surrounded with ANSI codes in my case but could be anything, emojis or something) and then that is used in its place. There would also be a function for command names.
EDIT: I am guessing that might mess up the length calculation for those, which is important for correct indentation / wrapping, but we can solve that by having the function return visual length.
The way forward is to use a SemanticDoc type internally, which annotates the Doc tree with what each printed item is (like, a command, or optional flag).
The user facing API should stay the same.
Then, the help generator would take those annotations, and convert them to ANSI codes.
I'm happy to consider PRs but I'm also pretty cautious here. Migrating to prettyprinter had some unexpected exponential blow ups.
Things to consider are opting out with the NOCOLOUR environment variable and in via modifiers.
So something like:
data HelpPrinterOptions = HelpPrinterOptions {
showSubgroup :: Text -> (Text, Int),
showCommandName :: Text -> (Text, Int),
showCommandUsage :: Text -> (Text, Int)
}
and then I could do something like
HelpPrinterOptions {
showSubgroup = \subgroupName -> (Term.style [Term.Bold] subgroupName, length subgroupName),
showCommandName = ...,
showCommandUsage = \u -> (u, length u)
}
The way forward is to use a SemanticDoc type internally, which annotates the Doc tree with what each printed item is (like, a command, or optional flag).
The user facing API should stay the same.
Then, the help generator would take those annotations, and convert them to ANSI codes.
I'm happy to consider PRs but I'm also pretty cautious here. Migrating to prettyprinter had some unexpected exponential blow ups.
Things to consider are opting out with the NOCOLOUR environment variable and in via modifiers.
I don't quite get how the styling would work then -> you would have predefined styles? Could user, via API, define styles for subgroups / commands? If API doesn't change, I don't see how they could?
There would be a new modifier to override reannotation.
The default would do nothing, but you could, for example, make optional things dull.
I should have said wouldn't change in a breaking way instead of stay the same.
Thanks @HuwCampbell -> I don't quite understand the details of what you described, as I probably don't know enough about optparse yet. I am most interested if this would allow relatively a lot of freedom to style our help usage -> but if I got it right, it would not, and would still be quite limited in what it offers?
I was hoping for such simple interface as the one I described, but I undrestand you had bad experience with pretty printing before. Still, to me it does sound like a feature that couldn't mess up much and would be quite on the edge of the existing logic -> but I don't know anything about the optparse codebase.
Thanks for your time to discuss this, I won't bother you more at the moment as I think the initial goal of sketching out some directions was accomplished.
Sorry I was on my phone so my responses were a bit brief. I was mostly talking about internals, but I think the end result will allow the sort of customisation you're after.
Sorry I was on my phone so my responses were a bit brief. I was mostly talking about internals, but I think the end result will allow the sort of customisation you're after.
Ah ok that does make more sense now! I don't know much about internals so I couldn't make much out of it. Thanks!
I read a bit of optparse internals now -> I get what you were saying about the Doc now. It is structure offered by prettyprinter package, and it is what prettyprinter takes an argument when printing.
What you do is convert Parser into ParserHelp, where ParserHelp is really just a bunch of Docs. I believe that happens here https://github.com/pcapriotti/optparse-applicative/blob/master/src/Options/Applicative/Help/Core.hs#L238 ? At that moment we lose information about which node in Doc is what -> semantic info.
I can see two solutions:
Doc ann
(based on https://hackage.haskell.org/package/prettyprinter-1.7.1/docs/Prettyprinter.html), I believe we just need to modify this inner type so that it contains more information -> to also contain information about what is the type of the node (usage, option name, subgroup title, ...)? And then we could use that in the Pretty module itself to look up appropriate user-defined functions for pretty printing and apply them at the right moment.What makes this a bit hard for me is that I don't have experience with free monads so I haven't yet grasped what Chunk is. Also, code is a bit dense at some points (short names, plenty of operators) so some parts will take me a bit longer to decifer.
Does this make sense as a general direction?
Hello! I'm having trouble finding a solution to this. Is something like this currently possible?
optparse-applicative version: 0.17.0.0
Currently, what I tried to so far -
but I got the "metavar" part of it colored green instead, not
myCommand
which is what I'm looking for: