From 27236703597114d143b9c35fcab7d0b2e3697429 Mon Sep 17 00:00:00 2001 From: Simon Boudrias Date: Tue, 30 Aug 2022 21:55:54 -0400 Subject: [PATCH] Allow clearing prompts once they're answered Fix #746 --- packages/confirm/demo.ts | 6 ++++++ packages/core/src/index.ts | 16 +++++++++++----- packages/core/src/lib/screen-manager.ts | 20 ++++++++++++++------ 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/packages/confirm/demo.ts b/packages/confirm/demo.ts index 01f77d899..09c3594a3 100644 --- a/packages/confirm/demo.ts +++ b/packages/confirm/demo.ts @@ -15,4 +15,10 @@ import confirm from './src/index.js'; default: false, }) ); + + console.log('This next prompt will be cleared on exit'); + console.log( + 'Cleared prompt answer:', + await confirm({ message: 'Confirm?' }, { clearPromptOnDone: true }) + ); })(); diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 05f852be3..2d6abf336 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -7,9 +7,10 @@ export { usePrefix } from './lib/prefix.js'; export * from './lib/key.js'; export * from './lib/Paginator.js'; -type StdioOptions = { +type Context = { input?: NodeJS.ReadableStream; output?: NodeJS.WritableStream; + clearPromptOnDone?: boolean; }; export type InquirerReadline = readline.ReadLine & { @@ -107,7 +108,7 @@ export type ResolvedPromptConfig = { export type Prompt = ( options: Config, - stdio?: StdioOptions + context?: Context ) => Promise; export function createPrompt( @@ -116,13 +117,13 @@ export function createPrompt( done: (value: Value) => void ) => string | [string, string | undefined] ) { - const prompt: Prompt = async (options, stdio) => { + const prompt: Prompt = async (options, context) => { // Default `input` to stdin - const input = stdio?.input ?? process.stdin; + const input = context?.input ?? process.stdin; // Add mute capabilities to the output const output = new MuteStream(); - output.pipe(stdio?.output ?? process.stdout); + output.pipe(context?.output ?? process.stdout); const rl = readline.createInterface({ terminal: true, @@ -140,6 +141,11 @@ export function createPrompt( while (len--) { cleanupHook(len); } + if (context?.clearPromptOnDone) { + screen.clean(); + } else { + screen.clearContent(); + } screen.done(); // Reset hooks state diff --git a/packages/core/src/lib/screen-manager.ts b/packages/core/src/lib/screen-manager.ts index 8d25d4ac9..dc85f5488 100644 --- a/packages/core/src/lib/screen-manager.ts +++ b/packages/core/src/lib/screen-manager.ts @@ -19,9 +19,9 @@ export default class ScreenManager { } render(content: string, bottomContent: string = '') { - this.rl.output.unmute(); - this.clean(this.extraLinesUnderPrompt); + this.clean(); + this.rl.output.unmute(); /** * Write message to screen and setPrompt to control backspace */ @@ -81,18 +81,26 @@ export default class ScreenManager { this.rl.output.mute(); } - clean(extraLines: number) { - util.down(this.rl, extraLines); + clean() { + this.rl.output.unmute(); + util.down(this.rl, this.extraLinesUnderPrompt); util.clearLine(this.rl, this.height); + + this.extraLinesUnderPrompt = 0; + this.rl.output.mute(); } - done() { + clearContent() { + this.rl.output.unmute(); // Reset the cursor at the end of the previously displayed content util.down(this.rl, this.extraLinesUnderPrompt); + this.rl.output.write('\n'); + this.rl.output.mute(); + } + done() { this.rl.setPrompt(''); this.rl.output.unmute(); - this.rl.output.write('\n'); this.rl.output.write(ansiEscapes.cursorShow); this.rl.output.end(); this.rl.close();