-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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
util: add colorize functionality #43523
Conversation
The colorize object allows to format strings with ansi color codes so that the string is stylized on a terminal. This is a utility function that should not yet be exposed to the users to allow some further polishing first. Signed-off-by: Ruben Bridgewater <ruben@bridgewater.de>
6da45e0
to
77f2290
Compare
) | ||
|
||
console.log( | ||
colorize.bold.underline.red('bold red underline') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would definitely prefer to avoid getters; both because it's a more confusing API, and because it's slower. i'd follow colors here, not chalk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Colors supports this notation? Manipulating the string prototype is not ideal (that's the original colors API).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh no, i meant colors/safe
:-) definitely nobody should use the colors
style :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am somewhat puzzled: that exact API is the one implemented here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, maybe i'm confused. i'd prefer colorize.bold().underline()
to colorize.bold.underline
, to be clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did consider that as well and I am open to using that, if it's what a majority prefers. Right now I would stick to the existing due to these reasons:
- Users of colors and chalk are used to it
- Passing a string to only the last call might also be confusing without a
.write()
/.format()
similar function - The performance should pretty much be identical and there should be room for improvement one way or the other (the implementation is already decent performance wise while chalk is still faster)
Can I ask, why are we moving established package functionality from the ecosystem into core? What is the goal by providing this as a standard module? |
@Qix- in this particular case, the established packages are not reliable. One has gone ESM-only, and the other was turned into malware by its maintainer. This is something core should have provided many years ago, but for these packages, and it's now critical it does so, for security and reliability reasons. |
added: REPLACEME | ||
--> | ||
|
||
The `util.colorize` object provides functions that add ansi color codes to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The `util.colorize` object provides functions that add ansi color codes to the | |
The `util.colorize` object provides functions that add ANSI color codes to the |
A citation for “ANSI color codes” would be a good addition.
// TODO(BridgeAR): Consider using a class instead and require the user to instantiate it | ||
// before using to declare their color support (or use a default, if none | ||
// provided). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why wouldn’t or couldn’t these be simple static functions that require no initialization? I mean, aren’t they essentially just prepending and appending \u001b[90m
and \u001b[39m
and the like?
As a user, I’d prefer they be as terse as possible. I’d be more likely to use them the simpler they are.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes and no: if we add more colors such as hex colors later on, we'll need to check that the terminal does indeed support the colors. Currently there's no way to do this besides a best effort check and we sometimes detect colors when not being supported and the other way around. Therefore I would like to provide a way to define the support by the user:
const { Colorize } = require('formatter')
const colorize256 = new Colorize({ colors: 256 })
console.log(
colorize256.bold.underline.hex('#123456')('bold underline fancy color')
)
Using Colorize.bold.underline.hex('#123456')('bold underline maybe fancy color')
could try to auto detect the supported colors while using the instance would be fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These feel like almost two use cases: a simple CLI tool like a test runner that needs only a handful of colors (or only green and red); and a more complicated CLI tool that wants lots of colors. The latter can call some kind of initialization function, since it’s somewhat expected that more work would be required to do something fancy; but ideally the simple case wouldn’t need much ceremony.
}); | ||
} | ||
|
||
for (const [style, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(inspect.colors))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to use primordials here? @aduh95
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not as important at the top level, but it'd probably be a good idea for consistency
What do you expect us to do when the TC-39 introduces fundamental language changes without any migration plan? We put off porting for literal years, and when it became more of a problem not to, now we're being told we're being hostile? Is Node just going to integrate every popular npm package at once? |
Let's please keep the discussion in this thread focused on the technical details of this PR. If you'd like to debate the feature itself, please open a discussion issue. Product debate on PR threads makes PRs difficult to review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few notes:
- what happens if colors are not available in the TTY?
- how could somebody override that setting?
I think we should provide a constructor too where this could be configured.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#43382 (comment) want to wait for this to conclude
I am closing this for now until we are able to resolve the discussion in #43382 |
The colorize object allows to format strings with ansi color codes
so that the string is stylized on a terminal.
This is a utility function that should not yet be exposed to the
users to allow some further polishing first.
This should be exposed under a completely new formatter module instead of adding new functionality to util.
Adding this functionality was discussed at the collaborator summit.
I played around with different builder APIs such as:
In the end I went with the latter, especially, due to chalk already using this.
Refs: #43382
Signed-off-by: Ruben Bridgewater ruben@bridgewater.de
@nodejs/util @nodejs/tooling PTAL.