3 const Prompt = require('../prompt');
4 const placeholder = require('../placeholder');
5 const { isPrimitive } = require('../utils');
7 class StringPrompt extends Prompt {
10 this.initial = isPrimitive(this.initial) ? String(this.initial) : '';
11 if (this.initial) this.cursorHide();
12 this.state.prevCursor = 0;
13 this.state.clipboard = [];
16 async keypress(input, key = {}) {
17 let prev = this.state.prevKeypress;
18 this.state.prevKeypress = key;
19 if (this.options.multiline === true && key.name === 'return') {
20 if (!prev || prev.name !== 'return') {
21 return this.append('\n', key);
24 return super.keypress(input, key);
32 this.input = this.value = '';
38 if (!ch || key.ctrl || key.code) return this.alert();
43 let { cursor, input } = this.state;
44 this.input = `${input}`.slice(0, cursor) + ch + `${input}`.slice(cursor);
45 this.moveCursor(String(ch).length);
54 let { cursor, input } = this.state;
55 if (cursor <= 0) return this.alert();
56 this.input = `${input}`.slice(0, cursor - 1) + `${input}`.slice(cursor);
62 let { cursor, input } = this.state;
63 if (input[cursor] === void 0) return this.alert();
64 this.input = `${input}`.slice(0, cursor) + `${input}`.slice(cursor + 1);
69 let pos = this.cursor;
70 if (this.input.length <= pos) return this.alert();
71 this.state.clipboard.push(this.input.slice(pos));
72 this.input = this.input.slice(0, pos);
77 let pos = this.cursor;
78 if (pos === 0) return this.alert();
79 let before = this.input.slice(0, pos);
80 let after = this.input.slice(pos);
81 let words = before.split(' ');
82 this.state.clipboard.push(words.pop());
83 this.input = words.join(' ');
84 this.cursor = this.input.length;
90 if (!this.state.clipboard.length) return this.alert();
91 this.insert(this.state.clipboard.pop());
96 if (this.state.prevCursor) {
97 this.cursor = this.state.prevCursor;
98 this.state.prevCursor = 0;
100 this.state.prevCursor = this.cursor;
112 this.cursor = this.input.length - 1;
117 let init = this.initial != null ? String(this.initial) : '';
118 if (!init || !init.startsWith(this.input)) return this.alert();
119 this.input = this.initial;
120 this.cursor = this.initial.length;
125 if (!this.input) return this.alert();
138 if (this.cursor >= this.input.length) return this.alert();
140 return this.render();
144 if (this.cursor <= 0) return this.alert();
146 return this.render();
153 async format(input = this.value) {
154 let initial = await this.resolve(this.initial, this.state);
155 if (!this.state.submitted) {
156 return placeholder(this, { input, initial, pos: this.cursor });
158 return this.styles.submitted(input || initial);
162 let size = this.state.size;
164 let prefix = await this.prefix();
165 let separator = await this.separator();
166 let message = await this.message();
168 let prompt = [prefix, message, separator].filter(Boolean).join(' ');
169 this.state.prompt = prompt;
171 let header = await this.header();
172 let output = await this.format();
173 let help = (await this.error()) || (await this.hint());
174 let footer = await this.footer();
176 if (help && !output.includes(help)) output += ' ' + help;
177 prompt += ' ' + output;
180 this.write([header, prompt, footer].filter(Boolean).join('\n'));
185 module.exports = StringPrompt;