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

WIP: render colours in help #539

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft

WIP: render colours in help #539

wants to merge 5 commits into from

Conversation

keynmol
Copy link
Contributor

@keynmol keynmol commented May 11, 2024

Primary goals:

  1. Colored output (exact design TBD)

CleanShot 2024-05-11 at 12 41 18

  1. Maintain compatibility

Non-goals:

  1. Extensibility (can happen later once we settle on theming design)

Copy link
Owner

@bkirwi bkirwi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few comments, but overall on board!

Will still need to take some care with compatibility breaking, but I don't see any reason why we shouldn't be able to ship this in a compatible way...

case object Colors extends HelpFormat {
override def colorsEnabled: Boolean = true
}
case class AutoColors(env: Map[String, String] = sys.env) extends HelpFormat {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat - was not aware of this!

This could be a method returning a format instead of a format of its own... and I'd prefer to not include sys.env as a default argument, since it's arguably not pure.

@@ -0,0 +1,27 @@
package com.monovore.decline

sealed abstract class HelpFormat extends Product with Serializable {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be tempted to define this on the Help companion so folks can refer to Help.Format and Help.Plain etc., but I don't feel so strongly.

|
|A header.
|
|Options and flags:
| --first, -F
| First option.
|
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do this without updating the existing spacing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I just always felt the default is a bit too crowded so thought I'd sneak it in :P Will revert.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah... I don't know if I disagree on an aesthetic level, but there are a lot of benefits to compactness in this context. (This change on its own makes this section ~50% larger, and now options get more spacing than section headers, which would probably want even more breathing room proportionately...)

import com.monovore.decline.HelpFormat.Plain
import com.monovore.decline.HelpFormat.Colors

private[decline] trait Theme {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't follow why we need both Theme and HelpFormat - seems like users could pass in a Theme directly. (And if we can get away with fewer concepts, strong preference for that!)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like users could pass in a Theme directly

I treat Theme interface as almost an implementation details - the methods in it are very tightly coupled to the help rendering logic (they're by no means the minimal set of methods required to render something), and I don't think it's beneficial (at this point) to expose this interface to users at all - because it'd increase compatibility surface.

Alternatively I could make it all 1 concept and make every method in Theme private to address the concerns from previous paragraph - but I felt like keeping Theme separate and private is the easiest w.r.t. API surface and flexibility.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's true that the fact that it's not user-facing does mitigate it to a large extent. Willing to keep it as is for now...

}

def optionList(opts: Opts[_]): Option[List[(Opt[_], Boolean)]] = opts match {
private[decline] case class HelpArgs(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat! This seems like something with this shape could eventually be cleaned up and made public for some of the fancier help-rendering ideas folks have had (HTML generation, etc.) but leaving it private for now seems like the right call.

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

Successfully merging this pull request may close these issues.

2 participants