| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 | 'use strict';const colors = require('ansi-colors');const interpolate = require('../interpolate');const Prompt = require('../prompt');class SnippetPrompt extends Prompt {  constructor(options) {    super(options);    this.cursorHide();    this.reset(true);  }  async initialize() {    this.interpolate = await interpolate(this);    await super.initialize();  }  async reset(first) {    this.state.keys = [];    this.state.invalid = new Map();    this.state.missing = new Set();    this.state.completed = 0;    this.state.values = {};    if (first !== true) {      await this.initialize();      await this.render();    }  }  moveCursor(n) {    let item = this.getItem();    this.cursor += n;    item.cursor += n;  }  dispatch(ch, key) {    if (!key.code && !key.ctrl && ch != null && this.getItem()) {      this.append(ch, key);      return;    }    this.alert();  }  append(ch, key) {    let item = this.getItem();    let prefix = item.input.slice(0, this.cursor);    let suffix = item.input.slice(this.cursor);    this.input = item.input = `${prefix}${ch}${suffix}`;    this.moveCursor(1);    this.render();  }  delete() {    let item = this.getItem();    if (this.cursor <= 0 || !item.input) return this.alert();    let suffix = item.input.slice(this.cursor);    let prefix = item.input.slice(0, this.cursor - 1);    this.input = item.input = `${prefix}${suffix}`;    this.moveCursor(-1);    this.render();  }  increment(i) {    return i >= this.state.keys.length - 1 ? 0 : i + 1;  }  decrement(i) {    return i <= 0 ? this.state.keys.length - 1 : i - 1;  }  first() {    this.state.index = 0;    this.render();  }  last() {    this.state.index = this.state.keys.length - 1;    this.render();  }  right() {    if (this.cursor >= this.input.length) return this.alert();    this.moveCursor(1);    this.render();  }  left() {    if (this.cursor <= 0) return this.alert();    this.moveCursor(-1);    this.render();  }  prev() {    this.state.index = this.decrement(this.state.index);    this.getItem();    this.render();  }  next() {    this.state.index = this.increment(this.state.index);    this.getItem();    this.render();  }  up() {    this.prev();  }  down() {    this.next();  }  format(value) {    let color = this.state.completed < 100 ? this.styles.warning : this.styles.success;    if (this.state.submitted === true && this.state.completed !== 100) {      color = this.styles.danger;    }    return color(`${this.state.completed}% completed`);  }  async render() {    let { index, keys = [], submitted, size } = this.state;    let newline = [this.options.newline, '\n'].find(v => v != null);    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 error = (await this.error()) || '';    let hint = (await this.hint()) || '';    let body = submitted ? '' : await this.interpolate(this.state);    let key = this.state.key = keys[index] || '';    let input = await this.format(key);    let footer = await this.footer();    if (input) prompt += ' ' + input;    if (hint && !input && this.state.completed === 0) prompt += ' ' + hint;    this.clear(size);    let lines = [header, prompt, body, footer, error.trim()];    this.write(lines.filter(Boolean).join(newline));    this.restore();  }  getItem(name) {    let { items, keys, index } = this.state;    let item = items.find(ch => ch.name === keys[index]);    if (item && item.input != null) {      this.input = item.input;      this.cursor = item.cursor;    }    return item;  }  async submit() {    if (typeof this.interpolate !== 'function') await this.initialize();    await this.interpolate(this.state, true);    let { invalid, missing, output, values } = this.state;    if (invalid.size) {      let err = '';      for (let [key, value] of invalid) err += `Invalid ${key}: ${value}\n`;      this.state.error = err;      return super.submit();    }    if (missing.size) {      this.state.error = 'Required: ' + [...missing.keys()].join(', ');      return super.submit();    }    let lines = colors.unstyle(output).split('\n');    let result = lines.map(v => v.slice(1)).join('\n');    this.value = { values, result };    return super.submit();  }}module.exports = SnippetPrompt;
 |