From b6355ef60290b59edbd31bc6139a33b8b41a5ef1 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Fri, 22 Feb 2019 19:15:07 +0100 Subject: [PATCH] tty: improve color detection 1) Using `process.env.TERM = 'dumb'` should never return any colors. 2) `process.env.TERM = 'terminator'` supports 24 bit colors. 3) Add support for `process.env.TERM = 'rxvt-unicode-24bit'` 4) `Hyper` does not support true colors anymore. It should fall back to the xterm settings in regular cases. 5) `process.env.COLORTERM = 'truecolor'` should return 24 bit colors. PR-URL: https://github.com/nodejs/node/pull/26264 Refs: https://github.com/nodejs/node/pull/26261 Reviewed-By: Anna Henningsen Reviewed-By: Jeremiah Senkpiel Reviewed-By: James M Snell --- lib/internal/tty.js | 49 +++++++++++---------- test/pseudo-tty/test-tty-get-color-depth.js | 12 +++-- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/lib/internal/tty.js b/lib/internal/tty.js index ea0bea4bfac94c..45f278d542c107 100644 --- a/lib/internal/tty.js +++ b/lib/internal/tty.js @@ -36,22 +36,25 @@ const COLORS_16m = 24; // Copyright (C) 1996-2016 Free Software Foundation, Inc. Copying and // distribution of this file, with or without modification, are permitted // provided the copyright notice and this notice are preserved. -const TERM_ENVS = [ - 'eterm', - 'cons25', - 'console', - 'cygwin', - 'dtterm', - 'gnome', - 'hurd', - 'jfbterm', - 'konsole', - 'kterm', - 'mlterm', - 'putty', - 'st', - 'terminator' -]; +const TERM_ENVS = { + 'eterm': COLORS_16, + 'cons25': COLORS_16, + 'console': COLORS_16, + 'cygwin': COLORS_16, + 'dtterm': COLORS_16, + 'gnome': COLORS_16, + 'hurd': COLORS_16, + 'jfbterm': COLORS_16, + 'konsole': COLORS_16, + 'kterm': COLORS_16, + 'mlterm': COLORS_16, + 'putty': COLORS_16, + 'st': COLORS_16, + // https://github.com/da-x/rxvt-unicode/tree/v9.22-with-24bit-color + 'rxvt-unicode-24bit': COLORS_16m, + // https://gist.github.com/XVilka/8346728#gistcomment-2823421 + 'terminator': COLORS_16m +}; const TERM_ENVS_REG_EXP = [ /ansi/, @@ -68,7 +71,7 @@ const TERM_ENVS_REG_EXP = [ // https://github.com/chalk/supports-color, // https://github.com/isaacs/color-support. function getColorDepth(env = process.env) { - if (env.NODE_DISABLE_COLORS || env.TERM === 'dumb' && !env.COLORTERM) { + if (env.NODE_DISABLE_COLORS || env.TERM === 'dumb') { return COLORS_2; } @@ -117,7 +120,6 @@ function getColorDepth(env = process.env) { } return COLORS_16m; case 'HyperTerm': - case 'Hyper': case 'MacTerm': return COLORS_16m; case 'Apple_Terminal': @@ -130,10 +132,8 @@ function getColorDepth(env = process.env) { const termEnv = env.TERM.toLowerCase(); - for (const term of TERM_ENVS) { - if (termEnv === term) { - return COLORS_16; - } + if (TERM_ENVS[termEnv]) { + return TERM_ENVS[termEnv]; } for (const term of TERM_ENVS_REG_EXP) { if (term.test(termEnv)) { @@ -142,8 +142,11 @@ function getColorDepth(env = process.env) { } } - if (env.COLORTERM) + if (env.COLORTERM) { + if (env.COLORTERM === 'truecolor' || env.COLORTERM === '24bit') + return COLORS_16m; return COLORS_16; + } return COLORS_2; } diff --git a/test/pseudo-tty/test-tty-get-color-depth.js b/test/pseudo-tty/test-tty-get-color-depth.js index d4062f5fdb6d39..14151ec3fb2f01 100644 --- a/test/pseudo-tty/test-tty-get-color-depth.js +++ b/test/pseudo-tty/test-tty-get-color-depth.js @@ -3,6 +3,7 @@ const common = require('../common'); const assert = require('assert').strict; const { WriteStream } = require('tty'); +const { inspect } = require('util'); const fd = common.getTTYfd(); const writeStream = new WriteStream(fd); @@ -16,6 +17,8 @@ const writeStream = new WriteStream(fd); // Check different environment variables. [ [{ COLORTERM: '1' }, 4], + [{ COLORTERM: 'truecolor' }, 24], + [{ COLORTERM: '24bit' }, 24], [{ TMUX: '1' }, 8], [{ CI: '1' }, 1], [{ CI: '1', TRAVIS: '1' }, 8], @@ -29,7 +32,7 @@ const writeStream = new WriteStream(fd); [{ TERM_PROGRAM: 'iTerm.app', TERM_PROGRAM_VERSION: '3.0' }, 24], [{ TERM_PROGRAM: 'iTerm.app', TERM_PROGRAM_VERSION: '2.0' }, 8], [{ TERM_PROGRAM: 'HyperTerm' }, 24], - [{ TERM_PROGRAM: 'Hyper' }, 24], + [{ TERM_PROGRAM: 'Hyper' }, 1], [{ TERM_PROGRAM: 'MacTerm' }, 24], [{ TERM_PROGRAM: 'Apple_Terminal' }, 8], [{ TERM: 'xterm-256' }, 8], @@ -40,13 +43,16 @@ const writeStream = new WriteStream(fd); [{ TERM: 'fail' }, 1], [{ NODE_DISABLE_COLORS: '1' }, 1], [{ TERM: 'dumb' }, 1], - [{ TERM: 'dumb', COLORTERM: '1' }, 4], + [{ TERM: 'dumb', COLORTERM: '1' }, 1], + [{ TERM: 'terminator' }, 24], + [{ TERM: 'console' }, 4] ].forEach(([env, depth], i) => { const actual = writeStream.getColorDepth(env); assert.strictEqual( actual, depth, - `i: ${i}, expected: ${depth}, actual: ${actual}, env: ${env}` + `i: ${i}, expected: ${depth}, ` + + `actual: ${actual}, env: ${inspect(env)}` ); });