crystal-lang / crystal

The Crystal Programming Language
https://crystal-lang.org
Apache License 2.0
19.48k stars 1.62k forks source link

Add `Colorize::Object#print` #15079

Open devnote-dev opened 1 month ago

devnote-dev commented 1 month ago

Quite simply, this method would print the ANSI codes to an optional IO (similar to how to_s operates). My primary use case for this is using colorize in regex expressions. At present, there aren't any good ways to handle colorize with regexes, especially when it comes to backreferences. For example, there's no way to use colorize with String#gsub:

require "colorize"

Colorize.enabled = false # not that this would do anything anyway

"foo|bar|baz".gsub(/\|(.+)\|/, "|\e[31m\\1\e[0m|") # => prints "foo|bar|baz" with "bar" in red

With this new method, it would allow for the following:

require "colorize"

Colorize.enabled = false

"foo|bar|baz".gsub(
  /\|(.+)\|/,
  "|#{Colorize.with.red.print}\\1#{Colorize.with.default.print}|"
) # => prints "foo|bar|baz" without colour/ANSI codes
Sija commented 1 month ago

There's no need for another method. What you're looking for is the #gsub with a block.

straight-shoota commented 1 month ago

@Sija I presume you'r referring to something like "foo|bar|baz".gsub(/\|(.+)\|/) { |match| match.colorize(:red) }? That's not even necessary the use case from OP can be achieved directly: "foo|bar|baz".gsub(/\|(.+)\|/, "|#{"\\1".colorize(:red)}|").

Apart from this specific use case, I think it might still be useful to offer a method to get the escape sequence of a specific Colorize::Object.