pcapriotti / optparse-applicative

Applicative option parser
BSD 3-Clause "New" or "Revised" License
910 stars 116 forks source link

Allow customization of help info via introducing semantic Doc #482

Open Martinsos opened 1 year ago

Martinsos commented 1 year ago

Should fix https://github.com/pcapriotti/optparse-applicative/issues/478 once it is done.

@HuwCampbell this is still more of a playground then a solution, and it doesn't even compile completely, but I think it is starting to take some initial shape, so I thought I would rather share while still in this early stage, so you can course-correct me if I am going in a very wrong direction.

I mostly asked questions in the code, in comments, about things that are not clear to me.

The approach is that I introduced a new type of Doc annotation, HelpAnn, which still allows for "old" AnsiStyle annotations (to support future feature of users specifying style via modifiers, and also the current feature of custom AnsiStyle docs they can already provide for some parts of docs like header, footer and similar), but also allows for HelpType annotations, which we use internally to annotate parts.

type HelpDoc = PP.Doc HelpAnn

data HelpAnn = HelpAnnType HelpType | HelpAnnStyle AnsiStyle

data HelpType = CmdName | OptionName | Description | Title | Metavar

The idea is then to later, probably at SimpleDocStream stage (in prettyprinter docs they recommend doing it at this stage), reannotate HelpAnn annotations into AnsiStyle annotations and continue from there same as before.

I haven't yet started at all working on modifiers that would allow users to specify custom style. For now, I just focused on replacing one kind of annotation with another kind of annotation. I mostly got stuck on figuring out where to exactly annotate what with our new semantic annotation (HelpAnn, specifically HelpAnnType), because I am having hard time figuring out which Chunk Doc is presenting what from the code -> is it option name, description, metavar, ... .

Once we have internal semantic annotation working, and a default way defined of converting those annotations (HelpAnn) into ansi annotations (AnsiStyle) (probably we will just do nothing for most of them), we can start looking into allowing users to define their own function that transforms HelpAnn into AnsiStyle as one way of (global) customization, and style modifiers as another way of (local) customization.

Interested to hear what you think, does this direction make sense? Thanks!

HuwCampbell commented 1 year ago

Hi.

Yes that's pretty much what I was suggesting. Please don't reformat everything in a PR though. It's too hard to tell what the point is.

Martinsos commented 1 year ago

Hi.

Yes that's pretty much what I was suggesting. Please don't reformat everything in a PR though. It's too hard to tell what the point is.

Ah sorry I didn't realize I was doing reformatting! That was ormolu doing it on its own. I will have to turn it off and then re-do the changes. In the meantime, do you have any pointers? You said direction seems to be ok, that is great -> what about good places to annotate stuff? I annotated on about two places, but I am not sure about some other places where I should do it. It would help if you could comment on the TODOs that I left in the code.

Martinsos commented 1 year ago

@HuwCampbell I reverted the formatting changes, so now it should be ready for a closer look!

HuwCampbell commented 1 year ago

I spent 10 minutes on the train and got it to this:

image
HuwCampbell commented 1 year ago

All up your approach it good. Do you mind if I push some commits to your branch?

Martinsos commented 1 year ago

That's looking great! @HuwCampbell sure pls go for it -> I am currently slammed with other work, but might be able to dedicate some more time in a couple of weeks. But if you can make progress / get it done in the meantime, none happier than me!

Btw this is what we currently have in our CLI, and what we would like to also achieve with optparse applicative:

image

So I am really hoping to achieve level of customizability that can bring us close to that.

This is what we achieved with optparse so far:

image

HuwCampbell commented 1 year ago

Will do. We're still a way to go though.

The issue isn't actually providing colours per se, that's relatively easy. I also want to respect if it's a TTY; environment variables like NOCOLOR; and a --no-color flag – while also giving a good programming API.

I general, if it's not a TTY, one shouldn't print colours; same for the other two ways of suppressing them. This gets a bit tricky for us because at the moment we don't have an environment parser to lean on internally.

Martinsos commented 1 year ago

Will do. We're still a way to go though.

The issue isn't actually providing colours per se, that's relatively easy. I also want to respect if it's a TTY; environment variables like NOCOLOR; and a --no-color flag – while also giving a good programming API.

I general, if it's not a TTY, one shouldn't print colours; same for the other two ways of suppressing them. This gets a bit tricky for us because at the moment we don't have an environment parser to lean on internally.

Ah interesting, I completely forgot about that. So we are really talking about the support for the ansi escape codes? And you are saying we don't have any logic for checking that at the moment + for propagating it to the right places?