Skip to content

Commit 4402b1a

Browse files
committed
repl: handle screen refresh for multiline input
Fixes an issue where when navigating a multiline input which exceeds terminal height, pressing UP arrow would not update the visible data when the cursor reaches the top. Fixes: #59938
1 parent 367bcce commit 4402b1a

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

lib/internal/readline/interface.js

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,11 @@ class Interface extends InterfaceConstructor {
364364
return Infinity;
365365
}
366366

367+
get rows() {
368+
if (this.output?.rows) return this.output.rows;
369+
return Infinity;
370+
}
371+
367372
/**
368373
* Sets the prompt written to the output.
369374
* @param {string} prompt
@@ -496,6 +501,7 @@ class Interface extends InterfaceConstructor {
496501
const dispPos = this[kGetDisplayPos](line);
497502
const lineCols = dispPos.cols;
498503
const lineRows = dispPos.rows;
504+
const terminalRows = this.rows;
499505

500506
// cursor position
501507
const cursorPos = this.getCursorPos();
@@ -513,11 +519,32 @@ class Interface extends InterfaceConstructor {
513519

514520
if (this[kIsMultiline]) {
515521
const lines = StringPrototypeSplit(this.line, '\n');
516-
// Write first line with normal prompt
517-
this[kWriteToOutput](this[kPrompt] + lines[0]);
518-
522+
// Normal case - display line from the first row to the last
523+
let startLine = 0;
524+
let endLine = lineRows;
525+
526+
const exceedsTerminal = lineRows >= terminalRows && terminalRows !== Infinity;
527+
if (exceedsTerminal) {
528+
const topOfVisibleData = lineRows - terminalRows;
529+
// The cursor starts from the last row. If it is within the
530+
// visible data segment, show the last part of the multiline data
531+
if (cursorPos.rows > topOfVisibleData) {
532+
startLine = topOfVisibleData;
533+
} else {
534+
// Cursor has traveled through the visible rows
535+
// Start displaying the data that the cursor is on
536+
// up until the terminal size allows
537+
startLine = cursorPos.rows;
538+
endLine = cursorPos.rows + terminalRows - 1;
539+
}
540+
}
541+
// If the first row is visible, show the normal prompt
542+
if (startLine === 0) {
543+
this[kWriteToOutput](this[kPrompt] + lines[0]);
544+
startLine++;
545+
}
519546
// For continuation lines, add the "|" prefix
520-
for (let i = 1; i < lines.length; i++) {
547+
for (let i = startLine; i <= endLine; i++) {
521548
this[kWriteToOutput](`\n${kMultilinePrompt.description}` + lines[i]);
522549
}
523550
} else {

0 commit comments

Comments
 (0)