--- /dev/null
+'use strict';
+
+const Prompt = require('../prompt');
+const placeholder = require('../placeholder');
+const { isPrimitive } = require('../utils');
+
+class StringPrompt extends Prompt {
+ constructor(options) {
+ super(options);
+ this.initial = isPrimitive(this.initial) ? String(this.initial) : '';
+ if (this.initial) this.cursorHide();
+ this.state.prevCursor = 0;
+ this.state.clipboard = [];
+ }
+
+ async keypress(input, key = {}) {
+ let prev = this.state.prevKeypress;
+ this.state.prevKeypress = key;
+ if (this.options.multiline === true && key.name === 'return') {
+ if (!prev || prev.name !== 'return') {
+ return this.append('\n', key);
+ }
+ }
+ return super.keypress(input, key);
+ }
+
+ moveCursor(n) {
+ this.cursor += n;
+ }
+
+ reset() {
+ this.input = this.value = '';
+ this.cursor = 0;
+ return this.render();
+ }
+
+ dispatch(ch, key) {
+ if (!ch || key.ctrl || key.code) return this.alert();
+ this.append(ch);
+ }
+
+ append(ch) {
+ let { cursor, input } = this.state;
+ this.input = `${input}`.slice(0, cursor) + ch + `${input}`.slice(cursor);
+ this.moveCursor(String(ch).length);
+ this.render();
+ }
+
+ insert(str) {
+ this.append(str);
+ }
+
+ delete() {
+ let { cursor, input } = this.state;
+ if (cursor <= 0) return this.alert();
+ this.input = `${input}`.slice(0, cursor - 1) + `${input}`.slice(cursor);
+ this.moveCursor(-1);
+ this.render();
+ }
+
+ deleteForward() {
+ let { cursor, input } = this.state;
+ if (input[cursor] === void 0) return this.alert();
+ this.input = `${input}`.slice(0, cursor) + `${input}`.slice(cursor + 1);
+ this.render();
+ }
+
+ cutForward() {
+ let pos = this.cursor;
+ if (this.input.length <= pos) return this.alert();
+ this.state.clipboard.push(this.input.slice(pos));
+ this.input = this.input.slice(0, pos);
+ this.render();
+ }
+
+ cutLeft() {
+ let pos = this.cursor;
+ if (pos === 0) return this.alert();
+ let before = this.input.slice(0, pos);
+ let after = this.input.slice(pos);
+ let words = before.split(' ');
+ this.state.clipboard.push(words.pop());
+ this.input = words.join(' ');
+ this.cursor = this.input.length;
+ this.input += after;
+ this.render();
+ }
+
+ paste() {
+ if (!this.state.clipboard.length) return this.alert();
+ this.insert(this.state.clipboard.pop());
+ this.render();
+ }
+
+ toggleCursor() {
+ if (this.state.prevCursor) {
+ this.cursor = this.state.prevCursor;
+ this.state.prevCursor = 0;
+ } else {
+ this.state.prevCursor = this.cursor;
+ this.cursor = 0;
+ }
+ this.render();
+ }
+
+ first() {
+ this.cursor = 0;
+ this.render();
+ }
+
+ last() {
+ this.cursor = this.input.length - 1;
+ this.render();
+ }
+
+ next() {
+ let init = this.initial != null ? String(this.initial) : '';
+ if (!init || !init.startsWith(this.input)) return this.alert();
+ this.input = this.initial;
+ this.cursor = this.initial.length;
+ this.render();
+ }
+
+ prev() {
+ if (!this.input) return this.alert();
+ this.reset();
+ }
+
+ backward() {
+ return this.left();
+ }
+
+ forward() {
+ return this.right();
+ }
+
+ right() {
+ if (this.cursor >= this.input.length) return this.alert();
+ this.moveCursor(1);
+ return this.render();
+ }
+
+ left() {
+ if (this.cursor <= 0) return this.alert();
+ this.moveCursor(-1);
+ return this.render();
+ }
+
+ isValue(value) {
+ return !!value;
+ }
+
+ async format(input = this.value) {
+ let initial = await this.resolve(this.initial, this.state);
+ if (!this.state.submitted) {
+ return placeholder(this, { input, initial, pos: this.cursor });
+ }
+ return this.styles.submitted(input || initial);
+ }
+
+ async render() {
+ let size = this.state.size;
+
+ let prefix = await this.prefix();
+ let separator = await this.separator();
+ let message = await this.message();
+
+ let prompt = [prefix, message, separator].filter(Boolean).join(' ');
+ this.state.prompt = prompt;
+
+ let header = await this.header();
+ let output = await this.format();
+ let help = (await this.error()) || (await this.hint());
+ let footer = await this.footer();
+
+ if (help && !output.includes(help)) output += ' ' + help;
+ prompt += ' ' + output;
+
+ this.clear(size);
+ this.write([header, prompt, footer].filter(Boolean).join('\n'));
+ this.restore();
+ }
+}
+
+module.exports = StringPrompt;