dry-cli icon indicating copy to clipboard operation
dry-cli copied to clipboard

Add functions to style text (colors, weight, etc)

Open gustavothecoder opened this issue 1 year ago • 7 comments

Inspired by the issue #121, I added a module with functions to change text style. The doc docsite/source/styling-your-output.html.md demonstrate how it works. I used the thor implementation as a basis, but I changed the API to make combinations shorter:

# Thor API
set_color "Hi!", :red, :on_white, :bold
# Implemented API
red(on_white(bold("Hi!")))

Resolve #121

gustavothecoder avatar Dec 02 '24 19:12 gustavothecoder

Maybe this API is a better idea because it looks more like Ruby:

stylize("Hi!").red.on_white.bold

In this case, stylize will return an object with methods to style the text.

gustavothecoder avatar Dec 04 '24 22:12 gustavothecoder

Maybe this API is a better idea because it looks more like Ruby:


stylize("Hi!").red.on_white.bold

In this case, stylize will return an object with methods to style the text.

First of all, thanks for doing this!

When I first read this PR, I also thought of this API :)

Want to go for it?

Also, can you extract some constants like BLUE = 34 and refactor from based on that?

cllns avatar Dec 05 '24 03:12 cllns

Maybe this API is a better idea because it looks more like Ruby:

stylize("Hi!").red.on_white.bold

In this case, stylize will return an object with methods to style the text.

First of all, thanks for doing this!

When I first read this PR, I also thought of this API :)

Want to go for it?

Also, can you extract some constants like BLUE = 34 and refactor from based on that?

Yeah, I'll let you know when I'm done refactoring.

gustavothecoder avatar Dec 06 '24 09:12 gustavothecoder

Hey @cllns, I'm done refactoring and I think that the solution is better now, what you think?

image

gustavothecoder avatar Dec 08 '24 12:12 gustavothecoder

Thanks for that refactoring! In reviewing it, I found a few more we can do as well

Thanks for the feedback! Can you review it again, please?

gustavothecoder avatar Dec 14 '24 18:12 gustavothecoder

Sweet, thanks!

Can you try to use recursion instead of mutation? In dry-rb, we prefer to leverage immutability, as we find it easier to reason about.

To spell it out, calling stylize("hello") would return a Dry::CLI::Styles::StyledText instance, then each call will wrap that in another Dry::CLI::Styles::StyledText instance, and so on. Then when .to_s is called, it adds the shell escape code and calls .to_s on its contents.

The StyledText can also hold the @escape_code. For the first call to style, that value will be nil and we can use that as a convention to throw the clear/reset at the end.

Does that make sense?

cllns avatar Jan 03 '25 21:01 cllns

Sweet, thanks!

Can you try to use recursion instead of mutation? In dry-rb, we prefer to leverage immutability, as we find it easier to reason about.

To spell it out, calling style("hello") would return a Dry::CLI::Styles::StyledText instance, then each call will wrap that in another Dry::CLI::Styles::StyledText instance, and so on. Then when .to_s is called, it adds the shell escape code and calls .to_s on its contents.

The StyledText can also hold the @escape_code. For the first call to style, that value will be nil and we can use that as a convention to throw the clear/reset at the end.

Does that make sense?

It does, the code is simpler now:

def chainable_update!(style, new_text)
  StyledText.new(
    select_graphic_rendition(style) + new_text,
    select_graphic_rendition(RESET)
  )
end

gustavothecoder avatar Jan 04 '25 12:01 gustavothecoder