GoScrobble/web/node_modules/enquirer/lib/prompts/autocomplete.js

114 lines
2.9 KiB
JavaScript

'use strict';
const Select = require('./select');
const highlight = (input, color) => {
let val = input.toLowerCase();
return str => {
let s = str.toLowerCase();
let i = s.indexOf(val);
let colored = color(str.slice(i, i + val.length));
return i >= 0 ? str.slice(0, i) + colored + str.slice(i + val.length) : str;
};
};
class AutoComplete extends Select {
constructor(options) {
super(options);
this.cursorShow();
}
moveCursor(n) {
this.state.cursor += n;
}
dispatch(ch) {
return this.append(ch);
}
space(ch) {
return this.options.multiple ? super.space(ch) : this.append(ch);
}
append(ch) {
let { cursor, input } = this.state;
this.input = input.slice(0, cursor) + ch + input.slice(cursor);
this.moveCursor(1);
return this.complete();
}
delete() {
let { cursor, input } = this.state;
if (!input) return this.alert();
this.input = input.slice(0, cursor - 1) + input.slice(cursor);
this.moveCursor(-1);
return this.complete();
}
deleteForward() {
let { cursor, input } = this.state;
if (input[cursor] === void 0) return this.alert();
this.input = `${input}`.slice(0, cursor) + `${input}`.slice(cursor + 1);
return this.complete();
}
number(ch) {
return this.append(ch);
}
async complete() {
this.completing = true;
this.choices = await this.suggest(this.input, this.state._choices);
this.state.limit = void 0; // allow getter/setter to reset limit
this.index = Math.min(Math.max(this.visible.length - 1, 0), this.index);
await this.render();
this.completing = false;
}
suggest(input = this.input, choices = this.state._choices) {
if (typeof this.options.suggest === 'function') {
return this.options.suggest.call(this, input, choices);
}
let str = input.toLowerCase();
return choices.filter(ch => ch.message.toLowerCase().includes(str));
}
pointer() {
return '';
}
format() {
if (!this.focused) return this.input;
if (this.options.multiple && this.state.submitted) {
return this.selected.map(ch => this.styles.primary(ch.message)).join(', ');
}
if (this.state.submitted) {
let value = this.value = this.input = this.focused.value;
return this.styles.primary(value);
}
return this.input;
}
async render() {
if (this.state.status !== 'pending') return super.render();
let style = this.options.highlight
? this.options.highlight.bind(this)
: this.styles.placeholder;
let color = highlight(this.input, style);
let choices = this.choices;
this.choices = choices.map(ch => ({ ...ch, message: color(ch.message) }));
await super.render();
this.choices = choices;
}
submit() {
if (this.options.multiple) {
this.value = this.selected.map(ch => ch.name);
}
return super.submit();
}
}
module.exports = AutoComplete;