Skip to content

Commit e6e98af

Browse files
BenoitZugmeyertargos
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 6fbad8b commit e6e98af

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

Diff for: lib/readline.js

+2-1
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);

Diff for: test/parallel/test-readline-interface.js

+18-1
Original file line numberDiff line numberDiff line change
@@ -1042,7 +1042,7 @@ function isWarned(emitter) {
10421042
rli.close();
10431043
}
10441044

1045-
// multi-line cursor position
1045+
// Multi-line input cursor position
10461046
{
10471047
const fi = new FakeInput();
10481048
const rli = new readline.Interface({
@@ -1059,6 +1059,23 @@ function isWarned(emitter) {
10591059
rli.close();
10601060
}
10611061

1062+
// Multi-line prompt cursor position
1063+
{
1064+
const fi = new FakeInput();
1065+
const rli = new readline.Interface({
1066+
input: fi,
1067+
output: fi,
1068+
prompt: '\nfilledline\nwraping text\n> ',
1069+
terminal: terminal
1070+
});
1071+
fi.columns = 10;
1072+
fi.emit('data', 't');
1073+
const cursorPos = rli._getCursorPos();
1074+
assert.strictEqual(cursorPos.rows, 4);
1075+
assert.strictEqual(cursorPos.cols, 3);
1076+
rli.close();
1077+
}
1078+
10621079
// Clear the whole screen
10631080
{
10641081
const fi = new FakeInput();

0 commit comments

Comments
 (0)