Skip to content

Commit bbf4019

Browse files
authored
fix: improved rendering clearing (#353)
Signed-off-by: Chapman Pendery <[email protected]>
1 parent 9ceea4f commit bbf4019

File tree

1 file changed

+35
-4
lines changed

1 file changed

+35
-4
lines changed

src/ui/ui-root.ts

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,20 @@ const writeOutput = (data: string) => {
2323
process.stdout.write(data);
2424
};
2525

26-
const _render = (term: ISTerm, suggestionManager: SuggestionManager, data: string, handlingBackspace: boolean): boolean => {
27-
const direction = term.getCursorState().remainingLines > MAX_LINES ? "below" : "above";
26+
const _render = (term: ISTerm, suggestionManager: SuggestionManager, data: string, handlingBackspace: boolean, handlingSuggestion: boolean): boolean => {
27+
const direction = _direction(term);
2828
const { hidden: cursorHidden, shift: cursorShift } = term.getCursorState();
2929
const linesOfInterest = MAX_LINES;
3030

3131
const suggestion = suggestionManager.render(direction);
3232
const hasSuggestion = suggestion.length != 0;
33+
34+
if (!handlingSuggestion && !hasSuggestion) {
35+
// there is no rendered suggestion and this will not render a suggestion
36+
writeOutput(data);
37+
return false;
38+
}
39+
3340
const commandState = term.getCommandState();
3441
const cursorTerminated = handlingBackspace ? true : commandState.cursorTerminated ?? false;
3542
const showSuggestions = hasSuggestion && cursorTerminated && !commandState.hasOutput && !cursorShift;
@@ -46,10 +53,28 @@ const _render = (term: ISTerm, suggestionManager: SuggestionManager, data: strin
4653
return showSuggestions;
4754
};
4855

56+
const _clear = (term: ISTerm): void => {
57+
const clearDirection = _direction(term) == "above" ? "below" : "above"; // invert direction to clear what was previously rendered
58+
const { hidden: cursorHidden } = term.getCursorState();
59+
const patch = term.getPatch(MAX_LINES, [], clearDirection);
60+
61+
const ansiCursorShow = cursorHidden ? "" : ansi.cursorShow;
62+
if (clearDirection == "above") {
63+
writeOutput(ansi.cursorHide + ansi.cursorSavePosition + ansi.cursorPrevLine.repeat(MAX_LINES) + patch + ansi.cursorRestorePosition + ansiCursorShow);
64+
} else {
65+
writeOutput(ansi.cursorHide + ansi.cursorSavePosition + ansi.cursorNextLine + patch + ansi.cursorRestorePosition + ansiCursorShow);
66+
}
67+
};
68+
69+
const _direction = (term: ISTerm): "above" | "below" => {
70+
return term.getCursorState().remainingLines > MAX_LINES ? "below" : "above";
71+
};
72+
4973
export const render = async (program: Command, shell: Shell, underTest: boolean, login: boolean) => {
5074
const term = await isterm.spawn(program, { shell, rows: process.stdout.rows, cols: process.stdout.columns, underTest, login });
5175
const suggestionManager = new SuggestionManager(term, shell);
5276
let hasSuggestion = false;
77+
let direction = _direction(term);
5378
let handlingBackspace = false; // backspace normally consistent of two data points (move back & delete), so on the first data point, we won't enforce the cursor terminated rule. this will help reduce flicker
5479
const stdinStartedInRawMode = process.stdin.isRaw;
5580
if (process.stdin.isTTY) process.stdin.setRawMode(true);
@@ -63,11 +88,17 @@ export const render = async (program: Command, shell: Shell, underTest: boolean,
6388
writeOutput(ansi.clearTerminal);
6489

6590
term.onData(async (data) => {
66-
hasSuggestion = _render(term, suggestionManager, data, handlingBackspace);
91+
const handlingDirectionChange = direction != _direction(term);
92+
if (handlingDirectionChange) {
93+
_clear(term);
94+
}
95+
96+
hasSuggestion = _render(term, suggestionManager, data, handlingBackspace, hasSuggestion);
6797
await suggestionManager.exec();
68-
hasSuggestion = _render(term, suggestionManager, "", handlingBackspace);
98+
hasSuggestion = _render(term, suggestionManager, "", handlingBackspace, hasSuggestion);
6999

70100
handlingBackspace = false;
101+
direction = _direction(term);
71102
});
72103

73104
process.stdin.on("keypress", (...keyPress: KeyPressEvent) => {

0 commit comments

Comments
 (0)