Skip to content

Commit

Permalink
tty: add hasColors function
Browse files Browse the repository at this point in the history
This adds a small wrapper around the `getColorDepth` function to check
if the stream supports at least a specific amount of colors. This is
convenient as the other API is not as straight forward and most use
cases likely only want to know if a specific amount of colors is
supported or not.

PR-URL: #26247
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Weijia Wang <starkwang@126.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
  • Loading branch information
BridgeAR authored and targos committed Mar 27, 2019
1 parent 9ce08c8 commit 070faf0
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 2 deletions.
30 changes: 30 additions & 0 deletions doc/api/tty.md
Expand Up @@ -176,6 +176,35 @@ corresponding to this `WriteStream`. The array is of the type
`[numColumns, numRows]` where `numColumns` and `numRows` represent the number
of columns and rows in the corresponding [TTY](tty.html).

### writeStream.hasColors([count][, env])
<!-- YAML
added: REPLACEME
-->

* `count` {integer} The number of colors that are requested (minimum 2).
**Default:** 16.
* `env` {Object} An object containing the environment variables to check. This
enables simulating the usage of a specific terminal. **Default:**
`process.env`.
* Returns: {boolean}

Returns `true` if the `writeStream` supports at least as many colors as provided
in `count`. Minimum support is 2 (black and white).

This has the same false positives and negatives as described in
[`writeStream.getColorDepth()`][].

```js
process.stdout.hasColors();
// Returns true or false depending on if `stdout` supports at least 16 colors.
process.stdout.hasColors(256);
// Returns true or false depending on if `stdout` supports at least 256 colors.
process.stdout.hasColors({ TMUX: '1' });
// Returns true.
process.stdout.hasColors(2 ** 24, { TMUX: '1' });
// Returns false (the environment setting pretends to support 2 ** 8 colors).
```

### writeStream.isTTY
<!-- YAML
added: v0.5.8
Expand Down Expand Up @@ -217,3 +246,4 @@ integer.
[`process.stderr`]: process.html#process_process_stderr
[`process.stdin`]: process.html#process_process_stdin
[`process.stdout`]: process.html#process_process_stdout
[`writeStream.getColorDepth()`]: #tty_writestream_getcolordepth_env
24 changes: 23 additions & 1 deletion lib/internal/tty.js
Expand Up @@ -22,6 +22,11 @@

'use strict';

const {
ERR_INVALID_ARG_TYPE,
ERR_OUT_OF_RANGE
} = require('internal/errors').codes;

let OSRelease;

const COLORS_2 = 1;
Expand Down Expand Up @@ -151,6 +156,23 @@ function getColorDepth(env = process.env) {
return COLORS_2;
}

function hasColors(count, env) {
if (env === undefined &&
(count === undefined || typeof count === 'object' && count !== null)) {
env = count;
count = 16;
} else {
if (typeof count !== 'number') {
throw new ERR_INVALID_ARG_TYPE('count', 'number', count);
}
if (count < 2) {
throw new ERR_OUT_OF_RANGE('count', '>= 2', count);
}
}
return count <= 2 ** getColorDepth(env);
}

module.exports = {
getColorDepth
getColorDepth,
hasColors
};
7 changes: 6 additions & 1 deletion lib/tty.js
Expand Up @@ -26,7 +26,10 @@ const net = require('net');
const { TTY, isTTY } = internalBinding('tty_wrap');
const errors = require('internal/errors');
const { ERR_INVALID_FD, ERR_TTY_INIT_FAILED } = errors.codes;
const { getColorDepth } = require('internal/tty');
const {
getColorDepth,
hasColors
} = require('internal/tty');

// Lazy loaded for startup performance.
let readline;
Expand Down Expand Up @@ -109,6 +112,8 @@ WriteStream.prototype.isTTY = true;

WriteStream.prototype.getColorDepth = getColorDepth;

WriteStream.prototype.hasColors = hasColors;

WriteStream.prototype._refreshSize = function() {
const oldCols = this.columns;
const oldRows = this.rows;
Expand Down
Expand Up @@ -12,8 +12,26 @@ const writeStream = new WriteStream(fd);
const depth = writeStream.getColorDepth();
assert.strictEqual(typeof depth, 'number');
assert(depth >= 1 && depth <= 24);

const support = writeStream.hasColors();
assert.strictEqual(support, depth !== 1);
}

// Validate invalid input.
[true, null, () => {}, Symbol(), 5n].forEach((input) => {
assert.throws(
() => writeStream.hasColors(input),
{ code: 'ERR_INVALID_ARG_TYPE' }
);
});

[-1, 1].forEach((input) => {
assert.throws(
() => writeStream.hasColors(input),
{ code: 'ERR_OUT_OF_RANGE' }
);
});

// Check different environment variables.
[
[{ COLORTERM: '1' }, 4],
Expand Down Expand Up @@ -54,6 +72,10 @@ const writeStream = new WriteStream(fd);
`i: ${i}, expected: ${depth}, ` +
`actual: ${actual}, env: ${inspect(env)}`
);
const colors = 2 ** actual;
assert(writeStream.hasColors(colors, env));
assert(!writeStream.hasColors(colors + 1, env));
assert(depth >= 4 ? writeStream.hasColors(env) : !writeStream.hasColors(env));
});

// OS settings
Expand Down
File renamed without changes.

0 comments on commit 070faf0

Please sign in to comment.