Skip to content

Commit

Permalink
Fix(@inquirer/core) Improve rendering performance (#1498)
Browse files Browse the repository at this point in the history
Fixes #1497
Related to #1407
  • Loading branch information
SBoudrias committed Aug 4, 2024
1 parent 8abfcd9 commit 4513828
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 53 deletions.
4 changes: 3 additions & 1 deletion packages/core/core.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,9 @@ describe('createPrompt()', () => {
events.keypress('enter');

await expect(answer).resolves.toEqual('done');
expect(getScreen({ raw: true })).toEqual(ansiEscapes.eraseLines(1));
expect(getScreen({ raw: true })).toEqual(
ansiEscapes.eraseLines(1) + ansiEscapes.cursorShow,
);
});

it('clear timeout when force closing', { timeout: 1000 }, async () => {
Expand Down
7 changes: 1 addition & 6 deletions packages/core/src/lib/create-prompt.mts
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,7 @@ export function createPrompt<Value, Config>(view: ViewFunction<Value, Config>) {
function onExit() {
hooksCleanup();

if (context?.clearPromptOnDone) {
screen.clean();
} else {
screen.clearContent();
}
screen.done();
screen.done({ clearContent: Boolean(context?.clearPromptOnDone) });

removeExitListener();
rl.input.removeListener('keypress', checkCursorPos);
Expand Down
71 changes: 25 additions & 46 deletions packages/core/src/lib/screen-manager.mts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import type { InquirerReadline } from '@inquirer/type';
const height = (content: string): number => content.split('\n').length;
const lastLine = (content: string): string => content.split('\n').pop() ?? '';

function cursorDown(n: number): string {
return n > 0 ? ansiEscapes.cursorDown(n) : '';
}

export default class ScreenManager {
// These variables are keeping information to allow correct prompt re-rendering
private height: number = 0;
Expand All @@ -18,11 +22,14 @@ export default class ScreenManager {
this.cursorPos = rl.getCursorPos();
}

render(content: string, bottomContent: string = '') {
/**
* Write message to screen and setPrompt to control backspace
*/
write(content: string) {
this.rl.output.unmute();
this.rl.output.write(content);
this.rl.output.mute();
}

render(content: string, bottomContent: string = '') {
// Write message to screen and setPrompt to control backspace
const promptLine = lastLine(content);
const rawPromptLine = stripAnsi(promptLine);

Expand Down Expand Up @@ -69,63 +76,35 @@ export default class ScreenManager {
// Return cursor to the initial left offset.
output += ansiEscapes.cursorTo(this.cursorPos.cols);

this.clean();
this.rl.output.unmute();

/**
* Set up state for next re-rendering
* Render and store state for future re-rendering
*/
this.write(
cursorDown(this.extraLinesUnderPrompt) +
ansiEscapes.eraseLines(this.height) +
output,
);

this.extraLinesUnderPrompt = bottomContentHeight;
this.height = height(output);

this.rl.output.write(output);
this.rl.output.mute();
}

checkCursorPos() {
const cursorPos = this.rl.getCursorPos();
if (cursorPos.cols !== this.cursorPos.cols) {
this.rl.output.unmute();
this.rl.output.write(ansiEscapes.cursorTo(cursorPos.cols));
this.rl.output.mute();
this.write(ansiEscapes.cursorTo(cursorPos.cols));
this.cursorPos = cursorPos;
}
}

clean() {
this.rl.output.unmute();
this.rl.output.write(
[
this.extraLinesUnderPrompt > 0
? ansiEscapes.cursorDown(this.extraLinesUnderPrompt)
: '',
ansiEscapes.eraseLines(this.height),
].join(''),
);
done({ clearContent }: { clearContent: boolean }) {
this.rl.setPrompt('');

this.extraLinesUnderPrompt = 0;
this.rl.output.mute();
}
let output = cursorDown(this.extraLinesUnderPrompt);
output += clearContent ? ansiEscapes.eraseLines(this.height) : '\n';
output += ansiEscapes.cursorShow;
this.write(output);

clearContent() {
this.rl.output.unmute();
// Reset the cursor at the end of the previously displayed content
this.rl.output.write(
[
this.extraLinesUnderPrompt > 0
? ansiEscapes.cursorDown(this.extraLinesUnderPrompt)
: '',
'\n',
].join(''),
);
this.rl.output.mute();
}

done() {
this.rl.setPrompt('');
this.rl.output.unmute();
this.rl.output.write(ansiEscapes.cursorShow);
this.rl.output.end();
this.rl.close();
}
}

0 comments on commit 4513828

Please sign in to comment.