tty: add hasColors function · nodejs/node@070faf0 (original) (raw)

5 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -176,6 +176,35 @@ corresponding to this `WriteStream`. The array is of the type
176 176 `[numColumns, numRows]` where `numColumns` and `numRows` represent the number
177 177 of columns and rows in the corresponding [TTY](tty.html).
178 178
179 +### writeStream.hasColors([count][, env])
180 +<!-- YAML
181 +added: REPLACEME
182 +-->
183 +
184 +* `count` {integer} The number of colors that are requested (minimum 2).
185 +**Default:** 16.
186 +* `env` {Object} An object containing the environment variables to check. This
187 + enables simulating the usage of a specific terminal. **Default:**
188 +`process.env`.
189 +* Returns: {boolean}
190 +
191 +Returns `true` if the `writeStream` supports at least as many colors as provided
192 +in `count`. Minimum support is 2 (black and white).
193 +
194 +This has the same false positives and negatives as described in
195 +[`writeStream.getColorDepth()`][].
196 +
197 +```js
198 +process.stdout.hasColors();
199 +// Returns true or false depending on if `stdout` supports at least 16 colors.
200 +process.stdout.hasColors(256);
201 +// Returns true or false depending on if `stdout` supports at least 256 colors.
202 +process.stdout.hasColors({ TMUX: '1' });
203 +// Returns true.
204 +process.stdout.hasColors(2 ** 24, { TMUX: '1' });
205 +// Returns false (the environment setting pretends to support 2 ** 8 colors).
206 +```
207 +
179 208 ### writeStream.isTTY
180 209 <!-- YAML
181 210 added: v0.5.8
@@ -217,3 +246,4 @@ integer.
217 246 [`process.stderr`]: process.html#process_process_stderr
218 247 [`process.stdin`]: process.html#process_process_stdin
219 248 [`process.stdout`]: process.html#process_process_stdout
249 +[`writeStream.getColorDepth()`]: #tty_writestream_getcolordepth_env
Original file line number Diff line number Diff line change
@@ -22,6 +22,11 @@
22 22
23 23 'use strict';
24 24
25 +const {
26 +ERR_INVALID_ARG_TYPE,
27 +ERR_OUT_OF_RANGE
28 +} = require('internal/errors').codes;
29 +
25 30 let OSRelease;
26 31
27 32 const COLORS_2 = 1;
@@ -151,6 +156,23 @@ function getColorDepth(env = process.env) {
151 156 return COLORS_2;
152 157 }
153 158
159 +function hasColors(count, env) {
160 +if (env === undefined &&
161 +(count === undefined |
162 +env = count;
163 +count = 16;
164 +} else {
165 +if (typeof count !== 'number') {
166 +throw new ERR_INVALID_ARG_TYPE('count', 'number', count);
167 +}
168 +if (count < 2) {
169 +throw new ERR_OUT_OF_RANGE('count', '>= 2', count);
170 +}
171 +}
172 +return count <= 2 ** getColorDepth(env);
173 +}
174 +
154 175 module.exports = {
155 - getColorDepth
176 + getColorDepth,
177 + hasColors
156 178 };
Original file line number Diff line number Diff line change
@@ -26,7 +26,10 @@ const net = require('net');
26 26 const { TTY, isTTY } = internalBinding('tty_wrap');
27 27 const errors = require('internal/errors');
28 28 const { ERR_INVALID_FD, ERR_TTY_INIT_FAILED } = errors.codes;
29 -const { getColorDepth } = require('internal/tty');
29 +const {
30 + getColorDepth,
31 + hasColors
32 +} = require('internal/tty');
30 33
31 34 // Lazy loaded for startup performance.
32 35 let readline;
@@ -109,6 +112,8 @@ WriteStream.prototype.isTTY = true;
109 112
110 113 WriteStream.prototype.getColorDepth = getColorDepth;
111 114
115 +WriteStream.prototype.hasColors = hasColors;
116 +
112 117 WriteStream.prototype._refreshSize = function() {
113 118 const oldCols = this.columns;
114 119 const oldRows = this.rows;
Original file line number Diff line number Diff line change
@@ -12,8 +12,26 @@ const writeStream = new WriteStream(fd);
12 12 const depth = writeStream.getColorDepth();
13 13 assert.strictEqual(typeof depth, 'number');
14 14 assert(depth >= 1 && depth <= 24);
15 +
16 +const support = writeStream.hasColors();
17 +assert.strictEqual(support, depth !== 1);
15 18 }
16 19
20 +// Validate invalid input.
21 +[true, null, () => {}, Symbol(), 5n].forEach((input) => {
22 +assert.throws(
23 +() => writeStream.hasColors(input),
24 +{ code: 'ERR_INVALID_ARG_TYPE' }
25 +);
26 +});
27 +
28 +[-1, 1].forEach((input) => {
29 +assert.throws(
30 +() => writeStream.hasColors(input),
31 +{ code: 'ERR_OUT_OF_RANGE' }
32 +);
33 +});
34 +
17 35 // Check different environment variables.
18 36 [
19 37 [{ COLORTERM: '1' }, 4],
@@ -54,6 +72,10 @@ const writeStream = new WriteStream(fd);
54 72 `i: i,expected:{i}, expected: i,expected:{depth}, ` +
55 73 `actual: actual,env:{actual}, env: actual,env:{inspect(env)}`
56 74 );
75 +const colors = 2 ** actual;
76 +assert(writeStream.hasColors(colors, env));
77 +assert(!writeStream.hasColors(colors + 1, env));
78 +assert(depth >= 4 ? writeStream.hasColors(env) : !writeStream.hasColors(env));
57 79 });
58 80
59 81 // OS settings

File renamed without changes.