3 const colors = require('ansi-colors');
4 const interpolate = require('../interpolate');
5 const Prompt = require('../prompt');
7 class SnippetPrompt extends Prompt {
15 this.interpolate = await interpolate(this);
16 await super.initialize();
21 this.state.invalid = new Map();
22 this.state.missing = new Set();
23 this.state.completed = 0;
24 this.state.values = {};
27 await this.initialize();
33 let item = this.getItem();
39 if (!key.code && !key.ctrl && ch != null && this.getItem()) {
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}`;
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}`;
66 return i >= this.state.keys.length - 1 ? 0 : i + 1;
70 return i <= 0 ? this.state.keys.length - 1 : i - 1;
79 this.state.index = this.state.keys.length - 1;
84 if (this.cursor >= this.input.length) return this.alert();
90 if (this.cursor <= 0) return this.alert();
96 this.state.index = this.decrement(this.state.index);
102 this.state.index = this.increment(this.state.index);
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;
120 return color(`${this.state.completed}% completed`);
124 let { index, keys = [], submitted, size } = this.state;
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();
131 let prompt = [prefix, message, separator].filter(Boolean).join(' ');
132 this.state.prompt = prompt;
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);
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;
146 let lines = [header, prompt, body, footer, error.trim()];
147 this.write(lines.filter(Boolean).join(newline));
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;
162 if (typeof this.interpolate !== 'function') await this.initialize();
163 await this.interpolate(this.state, true);
165 let { invalid, missing, output, values } = this.state;
168 for (let [key, value] of invalid) err += `Invalid ${key}: ${value}\n`;
169 this.state.error = err;
170 return super.submit();
174 this.state.error = 'Required: ' + [...missing.keys()].join(', ');
175 return super.submit();
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();
185 module.exports = SnippetPrompt;