I came across a use-case whereby I wanted people to be able to edit their previously submitted answers. I tried utilizing the filter and transformer attributes to no avail. I think the space-bar could be used for replacing the current answer in-memory with the default value. I can submit a PR if this is desired functionality.
I created a custom prompt that can be used to override the input type and will allow you to edit the default value by pressing the spacebar. The code is the same as the input prompt of inquirer with 5 added lines to onKeypress(). It can be found below:
"use strict";
const chalk = require("chalk");
const { map, takeUntil } = require("rxjs/operators");
const Base = require("inquirer/lib/prompts/base");
const observe = require("inquirer/lib/utils/events");
class InputPrompt extends Base {
/**
* Start the Inquiry session
* @param {Function} cb Callback when prompt is done
* @return {this}
*/
_run(cb) {
this.done = cb;
// Once user confirm (enter key)
const events = observe(this.rl);
const submit = events.line.pipe(map(this.filterInput.bind(this)));
const validation = this.handleSubmitEvents(submit);
validation.success.forEach(this.onEnd.bind(this));
validation.error.forEach(this.onError.bind(this));
events.keypress
.pipe(takeUntil(validation.success))
.forEach(this.onKeypress.bind(this));
// Init
this.render();
return this;
}
/**
* Render the prompt to screen
* @return {InputPrompt} self
*/
render(error) {
let bottomContent = "";
let appendContent = "";
let message = this.getQuestion();
const transformer = this.opt.transformer;
const isFinal = this.status === "answered";
if (isFinal) {
appendContent = this.answer;
} else {
appendContent = this.rl.line;
}
if (transformer) {
message += transformer(appendContent, this.answers, { isFinal });
} else {
message += isFinal ? chalk.cyan(appendContent) : appendContent;
}
if (error) {
bottomContent = chalk.red(">> ") + error;
}
this.screen.render(message, bottomContent);
}
/**
* When user press `enter` key
*/
filterInput(input) {
if (!input) {
return this.opt.default == null ? "" : this.opt.default;
}
return input;
}
onEnd(state) {
this.answer = state.value;
this.status = "answered";
// Re-render prompt
this.render();
this.screen.done();
this.done(state.value);
}
onError({ value = "", isValid }) {
this.rl.line += value;
this.rl.cursor += value.length;
this.render(isValid);
}
/**
* When user press a key
*/
onKeypress() {
// If user presses the space-bar as the first key and default value exists, replace current value with default value
if (this.rl.line === " " && this.opt.default) {
this.rl.line = this.opt.default;
this.rl.cursor = this.opt.default.length;
}
// If user press a key, just clear the default value
if (this.opt.default) {
this.opt.default = undefined;
}
// console.log("Keypress state A: ", this.rl);
// console.log("Keypress state B: ", this);
this.render();
}
}
module.exports = InputPrompt;
looking forward to this feature
I just extended class InputPrompt, really cool solution @alex-ppg
"use strict";
const InputPrompt = require("inquirer/lib/prompts/input");
class InputPromptWithDefaultEdit extends InputPrompt {
/**
* When user press a key
*/
onKeypress() {
// If user presses the space-bar as the first key and default value exists, replace current value with default value
if (this.rl.line === " " && this.opt.default) {
this.rl.line = this.opt.default;
this.rl.cursor = this.opt.default.length;
}
// If user press a key, just clear the default value
if (this.opt.default) {
this.opt.default = undefined;
}
this.render();
}
}
module.exports = InputPromptWithDefaultEdit;
Most helpful comment
I created a custom prompt that can be used to override the
inputtype and will allow you to edit thedefaultvalue by pressing the spacebar. The code is the same as theinputprompt ofinquirerwith 5 added lines toonKeypress(). It can be found below: