GeezerVison is showing github.com — tty: improve color terminal color detection · nodejs/node@ddab63a
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/internal/tty.js +34-11Lines changed: 34 additions & 11 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 24 | 24 |
| 25 | 25 | const { | 26 | 26 | ArrayPrototypeSome, | | 27 | + ObjectEntries, | | 28 | + ObjectPrototypeHasOwnProperty: hasOwn, | 27 | 29 | RegExpPrototypeExec, | | 30 | + SafeMap, | 28 | 31 | StringPrototypeSplit, | 29 | 32 | StringPrototypeToLowerCase, | 30 | 33 | } = primordials; | @@ -64,17 +67,31 @@ const TERM_ENVS = { | 64 | 67 | 'rxvt-unicode-24bit': COLORS_16m, | 65 | 68 | // https://bugs.launchpad.net/terminator/+bug/1030562 | 66 | 69 | 'terminator': COLORS_16m, | | 70 | + 'xterm-kitty': COLORS_16m, | 67 | 71 | }; | 68 | 72 |
| | 73 | +const CI_ENVS_MAP = new SafeMap(ObjectEntries({ | | 74 | + APPVEYOR: COLORS_256, | | 75 | + BUILDKITE: COLORS_256, | | 76 | + CIRCLECI: COLORS_16m, | | 77 | + DRONE: COLORS_256, | | 78 | + GITEA_ACTIONS: COLORS_16m, | | 79 | + GITHUB_ACTIONS: COLORS_16m, | | 80 | + GITLAB_CI: COLORS_256, | | 81 | + TRAVIS: COLORS_256, | | 82 | +})); | | 83 | + | 69 | 84 | const TERM_ENVS_REG_EXP = [ | 70 | 85 | /ansi/, | 71 | 86 | /color/, | 72 | 87 | /linux/, | | 88 | + /direct/, | 73 | 89 | /^con[0-9]*x[0-9]/, | 74 | 90 | /^rxvt/, | 75 | 91 | /^screen/, | 76 | 92 | /^xterm/, | 77 | 93 | /^vt100/, | | 94 | + /^vt220/, | 78 | 95 | ]; | 79 | 96 |
| 80 | 97 | let warned = false; | @@ -155,19 +172,21 @@ function getColorDepth(env = process.env) { | 155 | 172 | } | 156 | 173 |
| 157 | 174 | if (env.TMUX) { | 158 | | - return COLORS_256; | | 175 | + return COLORS_16m; | | 176 | + } | | 177 | + | | 178 | + // Azure DevOps | | 179 | + if (hasOwn(env, 'TF_BUILD') && hasOwn(env, 'AGENT_NAME')) { | | 180 | + return COLORS_16; | 159 | 181 | } | 160 | 182 |
| 161 | | - if (env.CI) { | 162 | | - if ([ | 163 | | - 'APPVEYOR', | 164 | | - 'BUILDKITE', | 165 | | - 'CIRCLECI', | 166 | | - 'DRONE', | 167 | | - 'GITHUB_ACTIONS', | 168 | | - 'GITLAB_CI', | 169 | | - 'TRAVIS', | 170 | | - ].some((sign) => sign in env) || env.CI_NAME === 'codeship') { | | 183 | + if (hasOwn(env, 'CI')) { | | 184 | + for (const { 0: envName, 1: colors } of CI_ENVS_MAP) { | | 185 | + if (hasOwn(env, envName)) { | | 186 | + return colors; | | 187 | + } | | 188 | + } | | 189 | + if (env.CI_NAME === 'codeship') { | 171 | 190 | return COLORS_256; | 172 | 191 | } | 173 | 192 | return COLORS_2; | @@ -198,6 +217,10 @@ function getColorDepth(env = process.env) { | 198 | 217 | } | 199 | 218 |
| 200 | 219 | if (env.TERM) { | | 220 | + if (RegExpPrototypeExec(/truecolor/, env.TERM) !== null) { | | 221 | + return COLORS_16m; | | 222 | + } | | 223 | + | 201 | 224 | if (RegExpPrototypeExec(/^xterm-256/, env.TERM) !== null) { | 202 | 225 | return COLORS_256; | 203 | 226 | } | |
Collapse file Copy file name to clipboardExpand all lines: test/pseudo-tty/test-tty-color-support.js +20-9Lines changed: 20 additions & 9 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -37,13 +37,18 @@ const writeStream = new WriteStream(fd); | 37 | 37 | [{ COLORTERM: '1' }, 4], | 38 | 38 | [{ COLORTERM: 'truecolor' }, 24], | 39 | 39 | [{ COLORTERM: '24bit' }, 24], | 40 | | - [{ TMUX: '1' }, 8], | | 40 | + [{ TMUX: '1' }, 24], | 41 | 41 | [{ CI: '1' }, 1], | 42 | | - [{ CI: '1', TRAVIS: '1' }, 8], | 43 | | - [{ CI: '1', CIRCLECI: '1' }, 8], | 44 | | - [{ CI: '1', APPVEYOR: '1' }, 8], | 45 | | - [{ CI: '1', GITLAB_CI: '1' }, 8], | | 42 | + [{ CI: '', APPVEYOR: '1' }, 8], | | 43 | + [{ CI: '1', BUILDKITE: '' }, 8], | 46 | 44 | [{ CI: '1', CI_NAME: 'codeship' }, 8], | | 45 | + [{ CI: '1', CIRCLECI: '1' }, 24], | | 46 | + [{ CI: '1', DRONE: '' }, 8], | | 47 | + [{ CI: '1', GITEA_ACTIONS: '' }, 24], | | 48 | + [{ CI: '1', GITHUB_ACTIONS: '' }, 24], | | 49 | + [{ CI: '1', GITLAB_CI: '1' }, 8], | | 50 | + [{ CI: '1', TRAVIS: '1' }, 8], | | 51 | + [{ CI: '', TRAVIS: '' }, 8], | 47 | 52 | [{ TEAMCITY_VERSION: '1.0.0' }, 1], | 48 | 53 | [{ TEAMCITY_VERSION: '9.11.0' }, 4], | 49 | 54 | [{ TERM_PROGRAM: 'iTerm.app' }, 8], | @@ -53,17 +58,22 @@ const writeStream = new WriteStream(fd); | 53 | 58 | [{ TERM_PROGRAM: 'Hyper' }, 1], | 54 | 59 | [{ TERM_PROGRAM: 'MacTerm' }, 24], | 55 | 60 | [{ TERM_PROGRAM: 'Apple_Terminal' }, 8], | 56 | | - [{ TERM: 'xterm-256' }, 8], | 57 | 61 | [{ TERM: 'ansi' }, 4], | 58 | 62 | [{ TERM: 'ANSI' }, 4], | 59 | 63 | [{ TERM: 'color' }, 4], | 60 | | - [{ TERM: 'linux' }, 4], | 61 | | - [{ TERM: 'fail' }, 1], | 62 | 64 | [{ TERM: 'color', NODE_DISABLE_COLORS: '1' }, 1], | | 65 | + [{ TERM: 'console' }, 4], | | 66 | + [{ TERM: 'direct' }, 4], | 63 | 67 | [{ TERM: 'dumb' }, 1], | 64 | 68 | [{ TERM: 'dumb', COLORTERM: '1' }, 1], | | 69 | + [{ TERM: 'fail' }, 1], | | 70 | + [{ TERM: 'linux' }, 4], | 65 | 71 | [{ TERM: 'terminator' }, 24], | 66 | | - [{ TERM: 'console' }, 4], | | 72 | + [{ TERM: 'vt100' }, 4], | | 73 | + [{ TERM: 'vt220' }, 4], | | 74 | + [{ TERM: 'xterm-256' }, 8], | | 75 | + [{ TERM: 'xterm-kitty' }, 24], | | 76 | + [{ TERM: 'xterm-truecolor' }, 24], | 67 | 77 | [{ COLORTERM: '24bit', FORCE_COLOR: '' }, 4], | 68 | 78 | [{ NO_COLOR: '1', FORCE_COLOR: '2' }, 8], | 69 | 79 | [{ NODE_DISABLE_COLORS: '1', FORCE_COLOR: '3' }, 24], | @@ -72,6 +82,7 @@ const writeStream = new WriteStream(fd); | 72 | 82 | [{ TMUX: '1', FORCE_COLOR: 0 }, 1], | 73 | 83 | [{ NO_COLOR: 'true', FORCE_COLOR: 0, COLORTERM: 'truecolor' }, 1], | 74 | 84 | [{ TERM: 'xterm-256color', COLORTERM: 'truecolor' }, 24], | | 85 | + [{ TF_BUILD: '', AGENT_NAME: '' }, 4], | 75 | 86 | ].forEach(([env, depth], i) => { | 76 | 87 | const actual = writeStream.getColorDepth(env); | 77 | 88 | assert.strictEqual( | |
|