Skip to content

Commit

Permalink
util: add more predefined color codes to inspect.colors
Browse files Browse the repository at this point in the history
This adds most commonly used ANSI color codes to
`util.inspect.colors`.

PR-URL: #30659
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com>
  • Loading branch information
BridgeAR authored and BethGriggs committed Feb 6, 2020
1 parent 68f6841 commit 6a55802
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 15 deletions.
67 changes: 63 additions & 4 deletions doc/api/util.md
Original file line number Diff line number Diff line change
Expand Up @@ -675,13 +675,72 @@ The default styles and associated colors are:
* `symbol`: `green`
* `undefined`: `grey`

The predefined color codes are: `white`, `grey`, `black`, `blue`, `cyan`,
`green`, `magenta`, `red` and `yellow`. There are also `bold`, `italic`,
`underline` and `inverse` codes.

Color styling uses ANSI control codes that may not be supported on all
terminals. To verify color support use [`tty.hasColors()`][].

Predefined control codes are listed below (grouped as "Modifiers", "Foreground
colors", and "Background colors").

#### Modifiers

Modifier support varies throughout different terminals. They will mostly be
ignored, if not supported.

* `reset` - Resets all (color) modifiers to their defaults
* **bold** - Make text bold
* _italic_ - Make text italic
* <span style="border-bottom: 1px;">underline</span> - Make text underlined
* ~~strikethrough~~ - Puts a horizontal line through the center of the text
(Alias: `strikeThrough`, `crossedout`, `crossedOut`)
* `hidden` - Prints the text, but makes it invisible (Alias: conceal)
* <span style="opacity: 0.5;">dim</span> - Decreased color intensity (Alias:
`faint`)
* <span style="border-top: 1px">overlined</span> - Make text overlined
* blink - Hides and shows the text in an interval
* <span style="filter: invert(100%)">inverse</span> - Swap foreground and
background colors (Alias: `swapcolors`, `swapColors`)
* <span style="border-bottom: 1px double;">doubleunderline</span> - Make text
double underlined (Alias: `doubleUnderline`)
* <span style="border: 1px">framed</span> - Draw a frame around the text

#### Foreground colors

* `black`
* `red`
* `green`
* `yellow`
* `blue`
* `magenta`
* `cyan`
* `white`
* `gray` (alias: `grey`, `blackBright`)
* `redBright`
* `greenBright`
* `yellowBright`
* `blueBright`
* `magentaBright`
* `cyanBright`
* `whiteBright`

#### Background colors

* `bgBlack`
* `bgRed`
* `bgGreen`
* `bgYellow`
* `bgBlue`
* `bgMagenta`
* `bgCyan`
* `bgWhite`
* `bgGray` (alias: `bgGrey`, `bgBlackBright`)
* `bgRedBright`
* `bgGreenBright`
* `bgYellowBright`
* `bgBlueBright`
* `bgMagentaBright`
* `bgCyanBright`
* `bgWhiteBright`

### Custom inspection functions on Objects

<!-- type=misc -->
Expand Down
86 changes: 75 additions & 11 deletions lib/internal/util/inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -269,23 +269,86 @@ ObjectDefineProperty(inspect, 'defaultOptions', {
}
});

// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
// Set Graphics Rendition http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
// Each color consists of an array with the color code as first entry and the
// reset code as second entry.
const defaultFG = 39;
const defaultBG = 49;
inspect.colors = ObjectAssign(ObjectCreate(null), {
reset: [0, 0],
bold: [1, 22],
dim: [2, 22], // Alias: faint
italic: [3, 23],
underline: [4, 24],
inverse: [7, 27],
white: [37, 39],
grey: [90, 39],
black: [30, 39],
blue: [34, 39],
cyan: [36, 39],
green: [32, 39],
magenta: [35, 39],
red: [31, 39],
yellow: [33, 39]
blink: [5, 25],
// Swap forground and background colors
inverse: [7, 27], // Alias: swapcolors, swapColors
hidden: [8, 28], // Alias: conceal
strikethrough: [9, 29], // Alias: strikeThrough, crossedout, crossedOut
doubleunderline: [21, 24], // Alias: doubleUnderline
black: [30, defaultFG],
red: [31, defaultFG],
green: [32, defaultFG],
yellow: [33, defaultFG],
blue: [34, defaultFG],
magenta: [35, defaultFG],
cyan: [36, defaultFG],
white: [37, defaultFG],
bgBlack: [40, defaultBG],
bgRed: [41, defaultBG],
bgGreen: [42, defaultBG],
bgYellow: [43, defaultBG],
bgBlue: [44, defaultBG],
bgMagenta: [45, defaultBG],
bgCyan: [46, defaultBG],
bgWhite: [47, defaultBG],
framed: [51, 54],
overlined: [53, 55],
gray: [90, defaultFG], // Alias: grey, blackBright
redBright: [91, defaultFG],
greenBright: [92, defaultFG],
yellowBright: [93, defaultFG],
blueBright: [94, defaultFG],
magentaBright: [95, defaultFG],
cyanBright: [96, defaultFG],
whiteBright: [97, defaultFG],
bgGray: [100, defaultBG], // Alias: bgGrey, bgBlackBright
bgRedBright: [101, defaultBG],
bgGreenBright: [102, defaultBG],
bgYellowBright: [103, defaultBG],
bgBlueBright: [104, defaultBG],
bgMagentaBright: [105, defaultBG],
bgCyanBright: [106, defaultBG],
bgWhiteBright: [107, defaultBG],
});

function defineColorAlias(target, alias) {
ObjectDefineProperty(inspect.colors, alias, {
get() {
return this[target];
},
set(value) {
this[target] = value;
},
configurable: true,
enumerable: false
});
}

defineColorAlias('gray', 'grey');
defineColorAlias('gray', 'blackBright');
defineColorAlias('bgGray', 'bgGrey');
defineColorAlias('bgGray', 'bgBlackBright');
defineColorAlias('dim', 'faint');
defineColorAlias('strikethrough', 'crossedout');
defineColorAlias('strikethrough', 'strikeThrough');
defineColorAlias('strikethrough', 'crossedOut');
defineColorAlias('hidden', 'conceal');
defineColorAlias('inverse', 'swapColors');
defineColorAlias('inverse', 'swapcolors');
defineColorAlias('doubleunderline', 'doubleUnderline');

// TODO(BridgeAR): Add function style support for more complex styles.
// Don't use 'blue' not visible on cmd.exe
inspect.styles = ObjectAssign(ObjectCreate(null), {
special: 'cyan',
Expand All @@ -298,6 +361,7 @@ inspect.styles = ObjectAssign(ObjectCreate(null), {
symbol: 'green',
date: 'magenta',
// "name": intentionally not styling
// TODO(BridgeAR): Highlight regular expressions properly.
regexp: 'red',
module: 'underline'
});
Expand Down
28 changes: 28 additions & 0 deletions test/parallel/test-util-inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -2072,6 +2072,34 @@ assert.strictEqual(inspect(new BigUint64Array([0n])), 'BigUint64Array [ 0n ]');
`\u001b[${string[0]}m'Oh no!'\u001b[${string[1]}m }`
);
rejection.catch(() => {});

// Verify that aliases do not show up as key while checking `inspect.colors`.
const colors = Object.keys(inspect.colors);
const aliases = Object.getOwnPropertyNames(inspect.colors)
.filter((c) => !colors.includes(c));
assert(!colors.includes('grey'));
assert(colors.includes('gray'));
// Verify that all aliases are correctly mapped.
for (const alias of aliases) {
assert(Array.isArray(inspect.colors[alias]));
}
// Check consistent naming.
[
'black',
'red',
'green',
'yellow',
'blue',
'magenta',
'cyan',
'white'
].forEach((color, i) => {
assert.deepStrictEqual(inspect.colors[color], [30 + i, 39]);
assert.deepStrictEqual(inspect.colors[`${color}Bright`], [90 + i, 39]);
const bgColor = `bg${color[0].toUpperCase()}${color.slice(1)}`;
assert.deepStrictEqual(inspect.colors[bgColor], [40 + i, 49]);
assert.deepStrictEqual(inspect.colors[`${bgColor}Bright`], [100 + i, 49]);
});
}

assert.strictEqual(
Expand Down

0 comments on commit 6a55802

Please sign in to comment.