.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / enquirer / lib / prompts / snippet.js
1 'use strict';
2
3 const colors = require('ansi-colors');
4 const interpolate = require('../interpolate');
5 const Prompt = require('../prompt');
6
7 class SnippetPrompt extends Prompt {
8   constructor(options) {
9     super(options);
10     this.cursorHide();
11     this.reset(true);
12   }
13
14   async initialize() {
15     this.interpolate = await interpolate(this);
16     await super.initialize();
17   }
18
19   async reset(first) {
20     this.state.keys = [];
21     this.state.invalid = new Map();
22     this.state.missing = new Set();
23     this.state.completed = 0;
24     this.state.values = {};
25
26     if (first !== true) {
27       await this.initialize();
28       await this.render();
29     }
30   }
31
32   moveCursor(n) {
33     let item = this.getItem();
34     this.cursor += n;
35     item.cursor += n;
36   }
37
38   dispatch(ch, key) {
39     if (!key.code && !key.ctrl && ch != null && this.getItem()) {
40       this.append(ch, key);
41       return;
42     }
43     this.alert();
44   }
45
46   append(ch, key) {
47     let item = this.getItem();
48     let prefix = item.input.slice(0, this.cursor);
49     let suffix = item.input.slice(this.cursor);
50     this.input = item.input = `${prefix}${ch}${suffix}`;
51     this.moveCursor(1);
52     this.render();
53   }
54
55   delete() {
56     let item = this.getItem();
57     if (this.cursor <= 0 || !item.input) return this.alert();
58     let suffix = item.input.slice(this.cursor);
59     let prefix = item.input.slice(0, this.cursor - 1);
60     this.input = item.input = `${prefix}${suffix}`;
61     this.moveCursor(-1);
62     this.render();
63   }
64
65   increment(i) {
66     return i >= this.state.keys.length - 1 ? 0 : i + 1;
67   }
68
69   decrement(i) {
70     return i <= 0 ? this.state.keys.length - 1 : i - 1;
71   }
72
73   first() {
74     this.state.index = 0;
75     this.render();
76   }
77
78   last() {
79     this.state.index = this.state.keys.length - 1;
80     this.render();
81   }
82
83   right() {
84     if (this.cursor >= this.input.length) return this.alert();
85     this.moveCursor(1);
86     this.render();
87   }
88
89   left() {
90     if (this.cursor <= 0) return this.alert();
91     this.moveCursor(-1);
92     this.render();
93   }
94
95   prev() {
96     this.state.index = this.decrement(this.state.index);
97     this.getItem();
98     this.render();
99   }
100
101   next() {
102     this.state.index = this.increment(this.state.index);
103     this.getItem();
104     this.render();
105   }
106
107   up() {
108     this.prev();
109   }
110
111   down() {
112     this.next();
113   }
114
115   format(value) {
116     let color = this.state.completed < 100 ? this.styles.warning : this.styles.success;
117     if (this.state.submitted === true && this.state.completed !== 100) {
118       color = this.styles.danger;
119     }
120     return color(`${this.state.completed}% completed`);
121   }
122
123   async render() {
124     let { index, keys = [], submitted, size } = this.state;
125
126     let newline = [this.options.newline, '\n'].find(v => v != null);
127     let prefix = await this.prefix();
128     let separator = await this.separator();
129     let message = await this.message();
130
131     let prompt = [prefix, message, separator].filter(Boolean).join(' ');
132     this.state.prompt = prompt;
133
134     let header = await this.header();
135     let error = (await this.error()) || '';
136     let hint = (await this.hint()) || '';
137     let body = submitted ? '' : await this.interpolate(this.state);
138
139     let key = this.state.key = keys[index] || '';
140     let input = await this.format(key);
141     let footer = await this.footer();
142     if (input) prompt += ' ' + input;
143     if (hint && !input && this.state.completed === 0) prompt += ' ' + hint;
144
145     this.clear(size);
146     let lines = [header, prompt, body, footer, error.trim()];
147     this.write(lines.filter(Boolean).join(newline));
148     this.restore();
149   }
150
151   getItem(name) {
152     let { items, keys, index } = this.state;
153     let item = items.find(ch => ch.name === keys[index]);
154     if (item && item.input != null) {
155       this.input = item.input;
156       this.cursor = item.cursor;
157     }
158     return item;
159   }
160
161   async submit() {
162     if (typeof this.interpolate !== 'function') await this.initialize();
163     await this.interpolate(this.state, true);
164
165     let { invalid, missing, output, values } = this.state;
166     if (invalid.size) {
167       let err = '';
168       for (let [key, value] of invalid) err += `Invalid ${key}: ${value}\n`;
169       this.state.error = err;
170       return super.submit();
171     }
172
173     if (missing.size) {
174       this.state.error = 'Required: ' + [...missing.keys()].join(', ');
175       return super.submit();
176     }
177
178     let lines = colors.unstyle(output).split('\n');
179     let result = lines.map(v => v.slice(1)).join('\n');
180     this.value = { values, result };
181     return super.submit();
182   }
183 }
184
185 module.exports = SnippetPrompt;