diff options
author | Anna Henningsen <anna@addaleax.net> | 2018-03-15 14:09:17 +0100 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2018-04-12 23:23:56 +0200 |
commit | 57e8793c4393aa3fafd87f289b19078b1918c166 (patch) | |
tree | a1076b73991a97ed829cf0da0e5747d611ccec78 /lib/console.js | |
parent | ce58df58d0360779d16d60ce3bb0e9979ec5fdf4 (diff) | |
download | node-new-57e8793c4393aa3fafd87f289b19078b1918c166.tar.gz |
console: add color support
Add a way to tell `Console` instances to either always use, never use
or auto-detect color support and inspect objects accordingly.
PR-URL: https://github.com/nodejs/node/pull/19372
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'lib/console.js')
-rw-r--r-- | lib/console.js | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/lib/console.js b/lib/console.js index 9557b27fbc..2c35e98223 100644 --- a/lib/console.js +++ b/lib/console.js @@ -26,6 +26,7 @@ const { codes: { ERR_CONSOLE_WRITABLE_STREAM, ERR_INVALID_ARG_TYPE, + ERR_INVALID_ARG_VALUE, }, } = require('internal/errors'); const { previewMapIterator, previewSetIterator } = require('internal/v8'); @@ -49,24 +50,32 @@ const { } = Array; // Track amount of indentation required via `console.group()`. -const kGroupIndent = Symbol('groupIndent'); +const kGroupIndent = Symbol('kGroupIndent'); + +const kFormatForStderr = Symbol('kFormatForStderr'); +const kFormatForStdout = Symbol('kFormatForStdout'); +const kGetInspectOptions = Symbol('kGetInspectOptions'); +const kColorMode = Symbol('kColorMode'); function Console(options /* or: stdout, stderr, ignoreErrors = true */) { if (!(this instanceof Console)) { return new Console(...arguments); } - let stdout, stderr, ignoreErrors; + let stdout, stderr, ignoreErrors, colorMode; if (options && typeof options.write !== 'function') { ({ stdout, stderr = stdout, - ignoreErrors = true + ignoreErrors = true, + colorMode = false } = options); } else { - stdout = options; - stderr = arguments[1]; - ignoreErrors = arguments[2] === undefined ? true : arguments[2]; + return new Console({ + stdout: options, + stderr: arguments[1], + ignoreErrors: arguments[2] + }); } if (!stdout || typeof stdout.write !== 'function') { @@ -94,7 +103,11 @@ function Console(options /* or: stdout, stderr, ignoreErrors = true */) { prop.value = createWriteErrorHandler(stderr); Object.defineProperty(this, '_stderrErrorHandler', prop); + if (typeof colorMode !== 'boolean' && colorMode !== 'auto') + throw new ERR_INVALID_ARG_VALUE('colorMode', colorMode); + this[kCounts] = new Map(); + this[kColorMode] = colorMode; Object.defineProperty(this, kGroupIndent, { writable: true }); this[kGroupIndent] = ''; @@ -156,13 +169,33 @@ function write(ignoreErrors, stream, string, errorhandler, groupIndent) { } } +const kColorInspectOptions = { colors: true }; +const kNoColorInspectOptions = {}; +Console.prototype[kGetInspectOptions] = function(stream) { + let color = this[kColorMode]; + if (color === 'auto') { + color = stream.isTTY && ( + typeof stream.getColorDepth === 'function' ? + stream.getColorDepth() > 2 : true); + } + + return color ? kColorInspectOptions : kNoColorInspectOptions; +}; + +Console.prototype[kFormatForStdout] = function(args) { + const opts = this[kGetInspectOptions](this._stdout); + return util.formatWithOptions(opts, ...args); +}; + +Console.prototype[kFormatForStderr] = function(args) { + const opts = this[kGetInspectOptions](this._stderr); + return util.formatWithOptions(opts, ...args); +}; + Console.prototype.log = function log(...args) { write(this._ignoreErrors, this._stdout, - // The performance of .apply and the spread operator seems on par in V8 - // 6.3 but the spread operator, unlike .apply(), pushes the elements - // onto the stack. That is, it makes stack overflows more likely. - util.format.apply(null, args), + this[kFormatForStdout](args), this._stdoutErrorHandler, this[kGroupIndent]); }; @@ -173,14 +206,16 @@ Console.prototype.dirxml = Console.prototype.log; Console.prototype.warn = function warn(...args) { write(this._ignoreErrors, this._stderr, - util.format.apply(null, args), + this[kFormatForStderr](args), this._stderrErrorHandler, this[kGroupIndent]); }; Console.prototype.error = Console.prototype.warn; Console.prototype.dir = function dir(object, options) { - options = Object.assign({ customInspect: false }, options); + options = Object.assign({ + customInspect: false + }, this[kGetInspectOptions](this._stdout), options); write(this._ignoreErrors, this._stdout, util.inspect(object, options), @@ -211,7 +246,7 @@ Console.prototype.timeEnd = function timeEnd(label = 'default') { Console.prototype.trace = function trace(...args) { const err = { name: 'Trace', - message: util.format.apply(null, args) + message: this[kFormatForStderr](args) }; Error.captureStackTrace(err, trace); this.error(err.stack); @@ -220,7 +255,7 @@ Console.prototype.trace = function trace(...args) { Console.prototype.assert = function assert(expression, ...args) { if (!expression) { args[0] = `Assertion failed${args.length === 0 ? '' : `: ${args[0]}`}`; - this.warn(util.format.apply(null, args)); + this.warn(this[kFormatForStderr](args)); } }; |