1 | 'use strict';
|
2 |
|
3 | var 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 |
|
18 | mods = extend({
|
19 |
|
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 |
|
29 | ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white']
|
30 | .reduce(function (obj, color, index) {
|
31 |
|
32 | obj[color] = { _fg: [30 + index, 39] };
|
33 | obj[color + 'Bright'] = { _fg: [90 + index, 39] };
|
34 |
|
35 |
|
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 |
|
45 |
|
46 |
|
47 | memoized = memoize(function (scope, mod) {
|
48 | return defineProperty(getFn(), '_cliColorData',
|
49 | d(extend({}, scope._cliColorData, mod)));
|
50 | });
|
51 |
|
52 | proto = Object.create(Function.prototype, extend(map(mods, function (mod) {
|
53 | return d.gs(function () { return memoized(this, mod); });
|
54 | }), {
|
55 |
|
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 |
|
72 | if (process.platform === 'win32') {
|
73 | xtermMatch = require('./_xterm-match');
|
74 | }
|
75 |
|
76 | getFn = 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 |
|
88 | getMove = function (control) {
|
89 | return function (num) {
|
90 | num = isNaN(num) ? 0 : max(floor(num), 0);
|
91 | return num ? ('\x1b[' + num + control) : '';
|
92 | };
|
93 | };
|
94 |
|
95 | module.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 | });
|