.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / enquirer / lib / utils.js
1 'use strict';
2
3 const toString = Object.prototype.toString;
4 const colors = require('ansi-colors');
5 let called = false;
6 let fns = [];
7
8 const complements = {
9   'yellow': 'blue',
10   'cyan': 'red',
11   'green': 'magenta',
12   'black': 'white',
13   'blue': 'yellow',
14   'red': 'cyan',
15   'magenta': 'green',
16   'white': 'black'
17 };
18
19 exports.longest = (arr, prop) => {
20   return arr.reduce((a, v) => Math.max(a, prop ? v[prop].length : v.length), 0);
21 };
22
23 exports.hasColor = str => !!str && colors.hasColor(str);
24
25 const isObject = exports.isObject = val => {
26   return val !== null && typeof val === 'object' && !Array.isArray(val);
27 };
28
29 exports.nativeType = val => {
30   return toString.call(val).slice(8, -1).toLowerCase().replace(/\s/g, '');
31 };
32
33 exports.isAsyncFn = val => {
34   return exports.nativeType(val) === 'asyncfunction';
35 };
36
37 exports.isPrimitive = val => {
38   return val != null && typeof val !== 'object' && typeof val !== 'function';
39 };
40
41 exports.resolve = (context, value, ...rest) => {
42   if (typeof value === 'function') {
43     return value.call(context, ...rest);
44   }
45   return value;
46 };
47
48 exports.scrollDown = (choices = []) => [...choices.slice(1), choices[0]];
49 exports.scrollUp = (choices = []) => [choices.pop(), ...choices];
50
51 exports.reorder = (arr = []) => {
52   let res = arr.slice();
53   res.sort((a, b) => {
54     if (a.index > b.index) return 1;
55     if (a.index < b.index) return -1;
56     return 0;
57   });
58   return res;
59 };
60
61 exports.swap = (arr, index, pos) => {
62   let len = arr.length;
63   let idx = pos === len ? 0 : pos < 0 ? len - 1 : pos;
64   let choice = arr[index];
65   arr[index] = arr[idx];
66   arr[idx] = choice;
67 };
68
69 exports.width = (stream, fallback = 80) => {
70   let columns = (stream && stream.columns) ? stream.columns : fallback;
71   if (stream && typeof stream.getWindowSize === 'function') {
72     columns = stream.getWindowSize()[0];
73   }
74   if (process.platform === 'win32') {
75     return columns - 1;
76   }
77   return columns;
78 };
79
80 exports.height = (stream, fallback = 20) => {
81   let rows = (stream && stream.rows) ? stream.rows : fallback;
82   if (stream && typeof stream.getWindowSize === 'function') {
83     rows = stream.getWindowSize()[1];
84   }
85   return rows;
86 };
87
88 exports.wordWrap = (str, options = {}) => {
89   if (!str) return str;
90
91   if (typeof options === 'number') {
92     options = { width: options };
93   }
94
95   let { indent = '', newline = ('\n' + indent), width = 80 } = options;
96   let spaces = (newline + indent).match(/[^\S\n]/g) || [];
97   width -= spaces.length;
98   let source = `.{1,${width}}([\\s\\u200B]+|$)|[^\\s\\u200B]+?([\\s\\u200B]+|$)`;
99   let output = str.trim();
100   let regex = new RegExp(source, 'g');
101   let lines = output.match(regex) || [];
102   lines = lines.map(line => line.replace(/\n$/, ''));
103   if (options.padEnd) lines = lines.map(line => line.padEnd(width, ' '));
104   if (options.padStart) lines = lines.map(line => line.padStart(width, ' '));
105   return indent + lines.join(newline);
106 };
107
108 exports.unmute = color => {
109   let name = color.stack.find(n => colors.keys.color.includes(n));
110   if (name) {
111     return colors[name];
112   }
113   let bg = color.stack.find(n => n.slice(2) === 'bg');
114   if (bg) {
115     return colors[name.slice(2)];
116   }
117   return str => str;
118 };
119
120 exports.pascal = str => str ? str[0].toUpperCase() + str.slice(1) : '';
121
122 exports.inverse = color => {
123   if (!color || !color.stack) return color;
124   let name = color.stack.find(n => colors.keys.color.includes(n));
125   if (name) {
126     let col = colors['bg' + exports.pascal(name)];
127     return col ? col.black : color;
128   }
129   let bg = color.stack.find(n => n.slice(0, 2) === 'bg');
130   if (bg) {
131     return colors[bg.slice(2).toLowerCase()] || color;
132   }
133   return colors.none;
134 };
135
136 exports.complement = color => {
137   if (!color || !color.stack) return color;
138   let name = color.stack.find(n => colors.keys.color.includes(n));
139   let bg = color.stack.find(n => n.slice(0, 2) === 'bg');
140   if (name && !bg) {
141     return colors[complements[name] || name];
142   }
143   if (bg) {
144     let lower = bg.slice(2).toLowerCase();
145     let comp = complements[lower];
146     if (!comp) return color;
147     return colors['bg' + exports.pascal(comp)] || color;
148   }
149   return colors.none;
150 };
151
152 exports.meridiem = date => {
153   let hours = date.getHours();
154   let minutes = date.getMinutes();
155   let ampm = hours >= 12 ? 'pm' : 'am';
156   hours = hours % 12;
157   let hrs = hours === 0 ? 12 : hours;
158   let min = minutes < 10 ? '0' + minutes : minutes;
159   return hrs + ':' + min + ' ' + ampm;
160 };
161
162 /**
163  * Set a value on the given object.
164  * @param {Object} obj
165  * @param {String} prop
166  * @param {any} value
167  */
168
169 exports.set = (obj = {}, prop = '', val) => {
170   return prop.split('.').reduce((acc, k, i, arr) => {
171     let value = arr.length - 1 > i ? (acc[k] || {}) : val;
172     if (!exports.isObject(value) && i < arr.length - 1) value = {};
173     return (acc[k] = value);
174   }, obj);
175 };
176
177 /**
178  * Get a value from the given object.
179  * @param {Object} obj
180  * @param {String} prop
181  */
182
183 exports.get = (obj = {}, prop = '', fallback) => {
184   let value = obj[prop] == null
185     ? prop.split('.').reduce((acc, k) => acc && acc[k], obj)
186     : obj[prop];
187   return value == null ? fallback : value;
188 };
189
190 exports.mixin = (target, b) => {
191   if (!isObject(target)) return b;
192   if (!isObject(b)) return target;
193   for (let key of Object.keys(b)) {
194     let desc = Object.getOwnPropertyDescriptor(b, key);
195     if (desc.hasOwnProperty('value')) {
196       if (target.hasOwnProperty(key) && isObject(desc.value)) {
197         let existing = Object.getOwnPropertyDescriptor(target, key);
198         if (isObject(existing.value)) {
199           target[key] = exports.merge({}, target[key], b[key]);
200         } else {
201           Reflect.defineProperty(target, key, desc);
202         }
203       } else {
204         Reflect.defineProperty(target, key, desc);
205       }
206     } else {
207       Reflect.defineProperty(target, key, desc);
208     }
209   }
210   return target;
211 };
212
213 exports.merge = (...args) => {
214   let target = {};
215   for (let ele of args) exports.mixin(target, ele);
216   return target;
217 };
218
219 exports.mixinEmitter = (obj, emitter) => {
220   let proto = emitter.constructor.prototype;
221   for (let key of Object.keys(proto)) {
222     let val = proto[key];
223     if (typeof val === 'function') {
224       exports.define(obj, key, val.bind(emitter));
225     } else {
226       exports.define(obj, key, val);
227     }
228   }
229 };
230
231 exports.onExit = callback => {
232   const onExit = (quit, code) => {
233     if (called) return;
234
235     called = true;
236     fns.forEach(fn => fn());
237
238     if (quit === true) {
239       process.exit(128 + code);
240     }
241   };
242
243   if (fns.length === 0) {
244     process.once('SIGTERM', onExit.bind(null, true, 15));
245     process.once('SIGINT', onExit.bind(null, true, 2));
246     process.once('exit', onExit);
247   }
248
249   fns.push(callback);
250 };
251
252 exports.define = (obj, key, value) => {
253   Reflect.defineProperty(obj, key, { value });
254 };
255
256 exports.defineExport = (obj, key, fn) => {
257   let custom;
258   Reflect.defineProperty(obj, key, {
259     enumerable: true,
260     configurable: true,
261     set(val) {
262       custom = val;
263     },
264     get() {
265       return custom ? custom() : fn();
266     }
267   });
268 };