diff --git a/benchmark.js b/benchmark.js index af90c06..2a071ef 100644 --- a/benchmark.js +++ b/benchmark.js @@ -21,4 +21,28 @@ suite('chalk', () => { bench('nested styles', () => { chalk.red('the fox jumps', chalk.underline.bgBlue('over the lazy dog') + '!'); }); + + const wrappedChalk = new chalk.constructor({ + wrapper: { + before: '@', + after: '#' + } + }); + + bench('wrapped single style', () => { + wrappedChalk.red('the fox jumps'); + }); + + bench('wrapped several styles', () => { + wrappedChalk.blue.bgRed.bold('the fox jumps over the lazy dog'); + }); + + const cachedWrapper = wrappedChalk.blue.bgRed.bold; + bench('cached wrapped styles', () => { + cachedWrapper('the fox jumps over the lazy dog'); + }); + + bench('nested wrapped styles', () => { + wrappedChalk.red('the fox jumps', wrappedChalk.underline.bgBlue('over the lazy dog') + '!'); + }); }); diff --git a/index.js b/index.js index ad9d4b3..0f30480 100644 --- a/index.js +++ b/index.js @@ -24,7 +24,7 @@ function applyOptions(obj, options) { obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; // By default, wrappers are empty strings - const defaultWrapper = {pre: '', post: ''}; + const defaultWrapper = {before: '', after: ''}; obj.wrapper = typeof options.wrapper === 'object' ? Object.assign({}, defaultWrapper, options.wrapper) : defaultWrapper; } @@ -196,8 +196,8 @@ function applyStyle() { // Replace any instances already present with a re-opening code // otherwise only the part of the string until said closing code // will be colored, and the rest will simply be 'plain'. - const open = this.wrapper.pre + code.open + this.wrapper.post; - const close = this.wrapper.pre + code.close + this.wrapper.post; + const open = this.wrapper.before + code.open + this.wrapper.after; + const close = this.wrapper.before + code.close + this.wrapper.after; str = open + str.replace(code.closeRe, code.open) + close; diff --git a/package.json b/package.json index 4b5f602..268b9f5 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "2.3.1", "description": "Terminal string styling done right", "license": "MIT", - "repository": "chalk/chalk", + "repository": "https://github.com/felipenmoura/chalk", "engines": { "node": ">=4" }, diff --git a/readme.md b/readme.md index 26b239b..72193d6 100644 --- a/readme.md +++ b/readme.md @@ -165,19 +165,36 @@ The wrapper marks the unprintable characters from style tags. A wrapper can be added to the styles, so you can escape characters or add marks to then. By default, these wrappers are empty strings `""`. -The wrappers object has two properties, `pre` and `post`. +The wrappers object has two properties, `before` and `after`. For example: ```js -const ctx = new chalk.constructor({wrapper: { - pre: '>', - post: '<', -}}); +const ctx = new chalk.constructor({ + wrapper: { + before: '>', + after: '<' + } +}); -ctx.red('foo') // outputs "><" +ctx.red('foo') // outputs ">\u001B[31m\u001B[39m<" ``` -This can be specially useful when escaping characters, using it into a _PS1_ string or debugging and outputing it into different terminals/TTYs. +This can be specially useful when escaping characters, using it into a _PS1_ string or debugging and outputing it into different terminals/TTYs. +That's because _PS1_ uses the number of _printable_ characters to know the length of the string and to position the cursor. If you don't mark the colour codes as "unprintable" by using `\[` and `\]`, those characteres will be used to determine the length of the string, mispositioning the cursor. + +```js +const ctx = new chalk.constructor({ + wrapper: { + before: '\\[', + after: '\\]' + } +}); + +ctx.red('foo') // outputs "\\[\u001B[31m\\]foo\\[\u001B[39m\\]" (marking the colour codes as unpritable) +``` + +That would output "foo" in red, as that is the printable result. + ### chalk.supportsColor diff --git a/test/wrapper.js b/test/wrapper.js index 156e4eb..402e4db 100644 --- a/test/wrapper.js +++ b/test/wrapper.js @@ -5,12 +5,14 @@ import test from 'ava'; // Spoof supports-color require('./_supports-color')(__dirname); -const m = require('..'); +const Chalk = require('..'); -m.wrapper = { - pre: '@', - post: '#' -}; +const m = new Chalk.constructor({ + wrapper: { + before: '@', + after: '#' + } +}); test('add wrapper to underline', t => { t.is(m.underline('foo'), '@\u001B[4m#foo@\u001B[24m#'); diff --git a/types/index.d.ts b/types/index.d.ts index c5a4708..6e4c959 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -11,12 +11,10 @@ export const enum Level { export interface ChalkOptions { enabled?: boolean; level?: Level; - wrapper?: Wrapper; -} - -export interface Wrapper { - pre: String, - post: String + wrapper?: { + before: String, + after: String + } } export interface ChalkConstructor { @@ -37,7 +35,6 @@ export interface Chalk { constructor: ChalkConstructor; enabled: boolean; level: Level; - wrapper: Wrapper; rgb(r: number, g: number, b: number): this; hsl(h: number, s: number, l: number): this; hsv(h: number, s: number, v: number): this;