UNPKG

4.25 kBJavaScriptView Raw
1'use strict';
2
3var d = require('es5-ext/lib/Object/descriptor')
4 , extend = require('es5-ext/lib/Object/extend')
5 , map = require('es5-ext/lib/Object/map')
6 , reduce = require('es5-ext/lib/Object/reduce')
7 , repeat = require('es5-ext/lib/String/prototype/repeat')
8 , memoize = require('memoizee')
9 , tty = require('tty')
10
11 , join = Array.prototype.join, defineProperty = Object.defineProperty
12 , defineProperties = Object.defineProperties, abs = Math.abs
13 , floor = Math.floor, max = Math.max, min = Math.min
14
15 , mods, proto, getFn, getMove, xtermMatch
16 , up, down, right, left, getHeight, memoized;
17
18mods = extend({
19 // Style
20 bold: { _bold: [1, 22] },
21 italic: { _italic: [3, 23] },
22 underline: { _underline: [4, 24] },
23 blink: { _blink: [5, 25] },
24 inverse: { _inverse: [7, 27] },
25 strike: { _strike: [9, 29] }
26},
27
28 // Color
29 ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white']
30 .reduce(function (obj, color, index) {
31 // foreground
32 obj[color] = { _fg: [30 + index, 39] };
33 obj[color + 'Bright'] = { _fg: [90 + index, 39] };
34
35 // background
36 obj['bg' + color[0].toUpperCase() + color.slice(1)] =
37 { _bg: [40 + index, 49] };
38 obj['bg' + color[0].toUpperCase() + color.slice(1) + 'Bright'] =
39 { _bg: [100 + index, 49] };
40
41 return obj;
42 }, {}));
43
44// Some use cli-color as: console.log(clc.red('Error!'));
45// Which is inefficient as on each call it configures new clc object
46// with memoization we reuse once created object
47memoized = memoize(function (scope, mod) {
48 return defineProperty(getFn(), '_cliColorData',
49 d(extend({}, scope._cliColorData, mod)));
50});
51
52proto = Object.create(Function.prototype, extend(map(mods, function (mod) {
53 return d.gs(function () { return memoized(this, mod); });
54}), {
55 // xterm (255) color
56 xterm: d(memoize(function (code) {
57 code = isNaN(code) ? 255 : min(max(code, 0), 255);
58 return defineProperty(getFn(), '_cliColorData',
59 d(extend({}, this._cliColorData, {
60 _fg: [xtermMatch ? xtermMatch[code] : ('38;5;' + code), 39]
61 })));
62 }, { method: 'xterm' })),
63 bgXterm: d(memoize(function (code) {
64 code = isNaN(code) ? 255 : min(max(code, 0), 255);
65 return defineProperty(getFn(), '_cliColorData',
66 d(extend({}, this._cliColorData, {
67 _bg: [xtermMatch ? (xtermMatch[code] + 10) : ('48;5;' + code), 49]
68 })));
69 }, { method: 'bgXterm' }))
70}));
71
72if (process.platform === 'win32') {
73 xtermMatch = require('./_xterm-match');
74}
75
76getFn = function () {
77 var fn = function (/*…msg*/) {
78 var data = fn._cliColorData, close = '';
79 return reduce(data, function (str, mod) {
80 close = '\x1b[' + mod[1] + 'm' + close;
81 return str + '\x1b[' + mod[0] + 'm';
82 }, '', true) + join.call(arguments, ' ') + close;
83 };
84 fn.__proto__ = proto;
85 return fn;
86};
87
88getMove = function (control) {
89 return function (num) {
90 num = isNaN(num) ? 0 : max(floor(num), 0);
91 return num ? ('\x1b[' + num + control) : '';
92 };
93};
94
95module.exports = defineProperties(getFn(), {
96 width: d.gs(process.stdout.getWindowSize ? function () {
97 return process.stdout.getWindowSize()[0];
98 } : function () {
99 return tty.getWindowSize ? tty.getWindowSize()[1] : 0;
100 }),
101 height: d.gs(getHeight = process.stdout.getWindowSize ? function () {
102 return process.stdout.getWindowSize()[1];
103 } : function () {
104 return tty.getWindowSize ? tty.getWindowSize()[0] : 0;
105 }),
106 reset: d.gs(function () {
107 return repeat.call('\n', getHeight() - 1) + '\x1bc';
108 }),
109 up: d(up = getMove('A')),
110 down: d(down = getMove('B')),
111 right: d(right = getMove('C')),
112 left: d(left = getMove('D')),
113 move: d(function (x, y) {
114 x = isNaN(x) ? 0 : floor(x);
115 y = isNaN(y) ? 0 : floor(y);
116 return ((x > 0) ? right(x) : left(-x)) + ((y > 0) ? down(y) : up(-y));
117 }),
118 moveTo: d(function (x, y) {
119 x = isNaN(x) ? 1 : (max(floor(x), 0) + 1);
120 y = isNaN(y) ? 1 : (max(floor(y), 0) + 1);
121 return '\x1b[' + y + ';' + x + 'H';
122 }),
123 bol: d(function (n/*, erase*/) {
124 var dir;
125 n = isNaN(n) ? 0 : Number(n);
126 dir = (n >= 0) ? 'E' : 'F';
127 n = floor(abs(n));
128 return arguments[1] ?
129 (((!n || (dir === 'F')) ? '\x1b[0E\x1bK' : '') +
130 repeat.call('\x1b[1' + dir + '\x1b[K', n)) : '\x1b[' + n + dir;
131 }),
132 beep: d('\x07'),
133 xtermSupported: d(!xtermMatch),
134 _cliColorData: d({})
135});