Skip to content

Commit 46a73b9

Browse files
BenoitZugmeyeraddaleax
authored andcommitted
readline: fix position computation
The implementation of _getDisplayPos, used to compute the cursor position and to find out how many lines to clear up when re-rendering the readline output, was counting each line (except the last one) from the input as one row, even if they were wraping. This caused some rendering issues when the 'prompt' have at least one wide line ending with a newline char, duplicating the lines at the top of the prompt when calling _refreshLine (ex: when the user hits backspace). This patch fixes the issue by computing the real rows count for each new line in the input string. PR-URL: #28272 Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent 285e036 commit 46a73b9

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

lib/readline.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,8 +732,9 @@ Interface.prototype._getDisplayPos = function(str) {
732732
i++;
733733
}
734734
if (code === 0x0a) { // new line \n
735+
// row must be incremented by 1 even if offset = 0 or col = +Infinity
736+
row += Math.ceil(offset / col) || 1;
735737
offset = 0;
736-
row += 1;
737738
continue;
738739
}
739740
const width = getStringWidth(code);

test/parallel/test-readline-interface.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1062,7 +1062,7 @@ function isWarned(emitter) {
10621062
rli.close();
10631063
}
10641064

1065-
// multi-line cursor position
1065+
// Multi-line input cursor position
10661066
{
10671067
const fi = new FakeInput();
10681068
const rli = new readline.Interface({
@@ -1079,6 +1079,23 @@ function isWarned(emitter) {
10791079
rli.close();
10801080
}
10811081

1082+
// Multi-line prompt cursor position
1083+
{
1084+
const fi = new FakeInput();
1085+
const rli = new readline.Interface({
1086+
input: fi,
1087+
output: fi,
1088+
prompt: '\nfilledline\nwraping text\n> ',
1089+
terminal: terminal
1090+
});
1091+
fi.columns = 10;
1092+
fi.emit('data', 't');
1093+
const cursorPos = rli._getCursorPos();
1094+
assert.strictEqual(cursorPos.rows, 4);
1095+
assert.strictEqual(cursorPos.cols, 3);
1096+
rli.close();
1097+
}
1098+
10821099
// Clear the whole screen
10831100
{
10841101
const fi = new FakeInput();

0 commit comments

Comments
 (0)