.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / enquirer / lib / prompts / survey.js
1 'use strict';
2
3 const ArrayPrompt = require('../types/array');
4
5 class Survey extends ArrayPrompt {
6   constructor(options = {}) {
7     super(options);
8     this.emptyError = options.emptyError || 'No items were selected';
9     this.term = process.env.TERM_PROGRAM;
10
11     if (!this.options.header) {
12       let header = ['', '4 - Strongly Agree', '3 - Agree', '2 - Neutral', '1 - Disagree', '0 - Strongly Disagree', ''];
13       header = header.map(ele => this.styles.muted(ele));
14       this.state.header = header.join('\n   ');
15     }
16   }
17
18   async toChoices(...args) {
19     if (this.createdScales) return false;
20     this.createdScales = true;
21     let choices = await super.toChoices(...args);
22     for (let choice of choices) {
23       choice.scale = createScale(5, this.options);
24       choice.scaleIdx = 2;
25     }
26     return choices;
27   }
28
29   dispatch() {
30     this.alert();
31   }
32
33   space() {
34     let choice = this.focused;
35     let ele = choice.scale[choice.scaleIdx];
36     let selected = ele.selected;
37     choice.scale.forEach(e => (e.selected = false));
38     ele.selected = !selected;
39     return this.render();
40   }
41
42   indicator() {
43     return '';
44   }
45
46   pointer() {
47     return '';
48   }
49
50   separator() {
51     return this.styles.muted(this.symbols.ellipsis);
52   }
53
54   right() {
55     let choice = this.focused;
56     if (choice.scaleIdx >= choice.scale.length - 1) return this.alert();
57     choice.scaleIdx++;
58     return this.render();
59   }
60
61   left() {
62     let choice = this.focused;
63     if (choice.scaleIdx <= 0) return this.alert();
64     choice.scaleIdx--;
65     return this.render();
66   }
67
68   indent() {
69     return '   ';
70   }
71
72   async renderChoice(item, i) {
73     await this.onChoice(item, i);
74     let focused = this.index === i;
75     let isHyper = this.term === 'Hyper';
76     let n = !isHyper ? 8 : 9;
77     let s = !isHyper ? ' ' : '';
78     let ln = this.symbols.line.repeat(n);
79     let sp = ' '.repeat(n + (isHyper ? 0 : 1));
80     let dot = enabled => (enabled ? this.styles.success('◉') : '◯') + s;
81
82     let num = i + 1 + '.';
83     let color = focused ? this.styles.heading : this.styles.noop;
84     let msg = await this.resolve(item.message, this.state, item, i);
85     let indent = this.indent(item);
86     let scale = indent + item.scale.map((e, i) => dot(i === item.scaleIdx)).join(ln);
87     let val = i => i === item.scaleIdx ? color(i) : i;
88     let next = indent + item.scale.map((e, i) => val(i)).join(sp);
89
90     let line = () => [num, msg].filter(Boolean).join(' ');
91     let lines = () => [line(), scale, next, ' '].filter(Boolean).join('\n');
92
93     if (focused) {
94       scale = this.styles.cyan(scale);
95       next = this.styles.cyan(next);
96     }
97
98     return lines();
99   }
100
101   async renderChoices() {
102     if (this.state.submitted) return '';
103     let choices = this.visible.map(async(ch, i) => await this.renderChoice(ch, i));
104     let visible = await Promise.all(choices);
105     if (!visible.length) visible.push(this.styles.danger('No matching choices'));
106     return visible.join('\n');
107   }
108
109   format() {
110     if (this.state.submitted) {
111       let values = this.choices.map(ch => this.styles.info(ch.scaleIdx));
112       return values.join(', ');
113     }
114     return '';
115   }
116
117   async render() {
118     let { submitted, size } = this.state;
119
120     let prefix = await this.prefix();
121     let separator = await this.separator();
122     let message = await this.message();
123
124     let prompt = [prefix, message, separator].filter(Boolean).join(' ');
125     this.state.prompt = prompt;
126
127     let header = await this.header();
128     let output = await this.format();
129     let help = await this.error() || await this.hint();
130     let body = await this.renderChoices();
131     let footer = await this.footer();
132
133     if (output || !help) prompt += ' ' + output;
134     if (help && !prompt.includes(help)) prompt += ' ' + help;
135
136     if (submitted && !output && !body && this.multiple && this.type !== 'form') {
137       prompt += this.styles.danger(this.emptyError);
138     }
139
140     this.clear(size);
141     this.write([prompt, header, body, footer].filter(Boolean).join('\n'));
142     this.restore();
143   }
144
145   submit() {
146     this.value = {};
147     for (let choice of this.choices) {
148       this.value[choice.name] = choice.scaleIdx;
149     }
150     return this.base.submit.call(this);
151   }
152 }
153
154 function createScale(n, options = {}) {
155   if (Array.isArray(options.scale)) {
156     return options.scale.map(ele => ({ ...ele }));
157   }
158   let scale = [];
159   for (let i = 1; i < n + 1; i++) scale.push({ i, selected: false });
160   return scale;
161 }
162
163 module.exports = Survey;