Skip to content

Commit 5b49ded

Browse files
Js-BrechtMylesBorins
authored andcommitted
readline: promote _getCursorPos to public api
Alias _getCursorPos() = getCursorPos() for backwards compatibility. Refs: #30347 PR-URL: #30687 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
1 parent 13b5ace commit 5b49ded

File tree

4 files changed

+54
-40
lines changed

4 files changed

+54
-40
lines changed

doc/api/readline.md

+13
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,19 @@ reading input from a TTY stream. The position of cursor determines the
398398
portion of the input string that will be modified as input is processed,
399399
as well as the column where the terminal caret will be rendered.
400400

401+
### rl.getCursorPos()
402+
<!-- YAML
403+
added: REPLACEME
404+
-->
405+
406+
* Returns: {Object}
407+
* `rows` {number} the row of the prompt the cursor currently lands on
408+
* `cols` {number} the screen column the cursor currently lands on
409+
410+
Returns the real position of the cursor in relation to the input
411+
prompt + string. Long input (wrapping) strings, as well as multiple
412+
line prompts are included in the calculations.
413+
401414
## readline.clearLine(stream, dir\[, callback\])
402415
<!-- YAML
403416
added: v0.7.7

lib/readline.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ Interface.prototype._refreshLine = function() {
367367
const lineRows = dispPos.rows;
368368

369369
// cursor position
370-
const cursorPos = this._getCursorPos();
370+
const cursorPos = this.getCursorPos();
371371

372372
// First move to the bottom of the current line, based on cursor pos
373373
const prevRows = this.prevRows || 0;
@@ -483,7 +483,7 @@ Interface.prototype._insertString = function(c) {
483483
this.line += c;
484484
this.cursor += c.length;
485485

486-
if (this._getCursorPos().cols === 0) {
486+
if (this.getCursorPos().cols === 0) {
487487
this._refreshLine();
488488
} else {
489489
this._writeToOutput(c);
@@ -750,7 +750,7 @@ Interface.prototype._getDisplayPos = function(str) {
750750

751751

752752
// Returns current cursor's position and line
753-
Interface.prototype._getCursorPos = function() {
753+
Interface.prototype.getCursorPos = function() {
754754
const columns = this.columns;
755755
const strBeforeCursor = this._prompt + this.line.substring(0, this.cursor);
756756
const dispPos = this._getDisplayPos(
@@ -767,20 +767,21 @@ Interface.prototype._getCursorPos = function() {
767767
}
768768
return { cols: cols, rows: rows };
769769
};
770+
Interface.prototype._getCursorPos = Interface.prototype.getCursorPos;
770771

771772

772773
// This function moves cursor dx places to the right
773774
// (-dx for left) and refreshes the line if it is needed
774775
Interface.prototype._moveCursor = function(dx) {
775776
const oldcursor = this.cursor;
776-
const oldPos = this._getCursorPos();
777+
const oldPos = this.getCursorPos();
777778
this.cursor += dx;
778779

779780
// bounds check
780781
if (this.cursor < 0) this.cursor = 0;
781782
else if (this.cursor > this.line.length) this.cursor = this.line.length;
782783

783-
const newPos = this._getCursorPos();
784+
const newPos = this.getCursorPos();
784785

785786
// Check if cursors are in the same line
786787
if (oldPos.rows === newPos.rows) {

test/parallel/test-readline-interface.js

+34-34
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ function isWarned(emitter) {
590590
rli.question(expectedLines[0], function() {
591591
rli.close();
592592
});
593-
const cursorPos = rli._getCursorPos();
593+
const cursorPos = rli.getCursorPos();
594594
assert.strictEqual(cursorPos.rows, 0);
595595
assert.strictEqual(cursorPos.cols, expectedLines[0].length);
596596
rli.close();
@@ -606,7 +606,7 @@ function isWarned(emitter) {
606606
rli.question(expectedLines.join('\n'), function() {
607607
rli.close();
608608
});
609-
const cursorPos = rli._getCursorPos();
609+
const cursorPos = rli.getCursorPos();
610610
assert.strictEqual(cursorPos.rows, expectedLines.length - 1);
611611
assert.strictEqual(cursorPos.cols, expectedLines.slice(-1)[0].length);
612612
rli.close();
@@ -623,11 +623,11 @@ function isWarned(emitter) {
623623
});
624624
fi.emit('data', 'the quick brown fox');
625625
fi.emit('keypress', '.', { ctrl: true, name: 'a' });
626-
let cursorPos = rli._getCursorPos();
626+
let cursorPos = rli.getCursorPos();
627627
assert.strictEqual(cursorPos.rows, 0);
628628
assert.strictEqual(cursorPos.cols, 0);
629629
fi.emit('keypress', '.', { ctrl: true, name: 'e' });
630-
cursorPos = rli._getCursorPos();
630+
cursorPos = rli.getCursorPos();
631631
assert.strictEqual(cursorPos.rows, 0);
632632
assert.strictEqual(cursorPos.cols, 19);
633633
rli.close();
@@ -643,28 +643,28 @@ function isWarned(emitter) {
643643
terminal: terminal
644644
});
645645
fi.emit('data', 'the quick brown fox');
646-
let cursorPos = rli._getCursorPos();
646+
let cursorPos = rli.getCursorPos();
647647
assert.strictEqual(cursorPos.rows, 0);
648648
assert.strictEqual(cursorPos.cols, 19);
649649

650650
// Back one character
651651
fi.emit('keypress', '.', { ctrl: true, name: 'b' });
652-
cursorPos = rli._getCursorPos();
652+
cursorPos = rli.getCursorPos();
653653
assert.strictEqual(cursorPos.rows, 0);
654654
assert.strictEqual(cursorPos.cols, 18);
655655
// Back one character
656656
fi.emit('keypress', '.', { ctrl: true, name: 'b' });
657-
cursorPos = rli._getCursorPos();
657+
cursorPos = rli.getCursorPos();
658658
assert.strictEqual(cursorPos.rows, 0);
659659
assert.strictEqual(cursorPos.cols, 17);
660660
// Forward one character
661661
fi.emit('keypress', '.', { ctrl: true, name: 'f' });
662-
cursorPos = rli._getCursorPos();
662+
cursorPos = rli.getCursorPos();
663663
assert.strictEqual(cursorPos.rows, 0);
664664
assert.strictEqual(cursorPos.cols, 18);
665665
// Forward one character
666666
fi.emit('keypress', '.', { ctrl: true, name: 'f' });
667-
cursorPos = rli._getCursorPos();
667+
cursorPos = rli.getCursorPos();
668668
assert.strictEqual(cursorPos.rows, 0);
669669
assert.strictEqual(cursorPos.cols, 19);
670670
rli.close();
@@ -683,13 +683,13 @@ function isWarned(emitter) {
683683

684684
// Move left one character/code point
685685
fi.emit('keypress', '.', { name: 'left' });
686-
let cursorPos = rli._getCursorPos();
686+
let cursorPos = rli.getCursorPos();
687687
assert.strictEqual(cursorPos.rows, 0);
688688
assert.strictEqual(cursorPos.cols, 0);
689689

690690
// Move right one character/code point
691691
fi.emit('keypress', '.', { name: 'right' });
692-
cursorPos = rli._getCursorPos();
692+
cursorPos = rli.getCursorPos();
693693
assert.strictEqual(cursorPos.rows, 0);
694694
if (common.hasIntl) {
695695
assert.strictEqual(cursorPos.cols, 2);
@@ -717,12 +717,12 @@ function isWarned(emitter) {
717717

718718
// Move left one character/code point
719719
fi.emit('keypress', '.', { name: 'left' });
720-
let cursorPos = rli._getCursorPos();
720+
let cursorPos = rli.getCursorPos();
721721
assert.strictEqual(cursorPos.rows, 0);
722722
assert.strictEqual(cursorPos.cols, 0);
723723

724724
fi.emit('data', '🐕');
725-
cursorPos = rli._getCursorPos();
725+
cursorPos = rli.getCursorPos();
726726
assert.strictEqual(cursorPos.rows, 0);
727727

728728
if (common.hasIntl) {
@@ -753,7 +753,7 @@ function isWarned(emitter) {
753753

754754
// Move left one character/code point
755755
fi.emit('keypress', '.', { name: 'right' });
756-
let cursorPos = rli._getCursorPos();
756+
let cursorPos = rli.getCursorPos();
757757
assert.strictEqual(cursorPos.rows, 0);
758758
if (common.hasIntl) {
759759
assert.strictEqual(cursorPos.cols, 2);
@@ -764,7 +764,7 @@ function isWarned(emitter) {
764764
}
765765

766766
fi.emit('data', '🐕');
767-
cursorPos = rli._getCursorPos();
767+
cursorPos = rli.getCursorPos();
768768
assert.strictEqual(cursorPos.rows, 0);
769769
if (common.hasIntl) {
770770
assert.strictEqual(cursorPos.cols, 4);
@@ -790,19 +790,19 @@ function isWarned(emitter) {
790790
});
791791
fi.emit('data', 'the quick brown fox');
792792
fi.emit('keypress', '.', { ctrl: true, name: 'left' });
793-
let cursorPos = rli._getCursorPos();
793+
let cursorPos = rli.getCursorPos();
794794
assert.strictEqual(cursorPos.rows, 0);
795795
assert.strictEqual(cursorPos.cols, 16);
796796
fi.emit('keypress', '.', { meta: true, name: 'b' });
797-
cursorPos = rli._getCursorPos();
797+
cursorPos = rli.getCursorPos();
798798
assert.strictEqual(cursorPos.rows, 0);
799799
assert.strictEqual(cursorPos.cols, 10);
800800
fi.emit('keypress', '.', { ctrl: true, name: 'right' });
801-
cursorPos = rli._getCursorPos();
801+
cursorPos = rli.getCursorPos();
802802
assert.strictEqual(cursorPos.rows, 0);
803803
assert.strictEqual(cursorPos.cols, 16);
804804
fi.emit('keypress', '.', { meta: true, name: 'f' });
805-
cursorPos = rli._getCursorPos();
805+
cursorPos = rli.getCursorPos();
806806
assert.strictEqual(cursorPos.rows, 0);
807807
assert.strictEqual(cursorPos.cols, 19);
808808
rli.close();
@@ -904,13 +904,13 @@ function isWarned(emitter) {
904904
terminal: terminal
905905
});
906906
fi.emit('data', 'the quick brown fox');
907-
let cursorPos = rli._getCursorPos();
907+
let cursorPos = rli.getCursorPos();
908908
assert.strictEqual(cursorPos.rows, 0);
909909
assert.strictEqual(cursorPos.cols, 19);
910910

911911
// Delete left character
912912
fi.emit('keypress', '.', { ctrl: true, name: 'h' });
913-
cursorPos = rli._getCursorPos();
913+
cursorPos = rli.getCursorPos();
914914
assert.strictEqual(cursorPos.rows, 0);
915915
assert.strictEqual(cursorPos.cols, 18);
916916
rli.on('line', common.mustCall((line) => {
@@ -930,7 +930,7 @@ function isWarned(emitter) {
930930
terminal: terminal
931931
});
932932
fi.emit('data', '💻');
933-
let cursorPos = rli._getCursorPos();
933+
let cursorPos = rli.getCursorPos();
934934
assert.strictEqual(cursorPos.rows, 0);
935935
if (common.hasIntl) {
936936
assert.strictEqual(cursorPos.cols, 2);
@@ -939,7 +939,7 @@ function isWarned(emitter) {
939939
}
940940
// Delete left character
941941
fi.emit('keypress', '.', { ctrl: true, name: 'h' });
942-
cursorPos = rli._getCursorPos();
942+
cursorPos = rli.getCursorPos();
943943
assert.strictEqual(cursorPos.rows, 0);
944944
assert.strictEqual(cursorPos.cols, 0);
945945
rli.on('line', common.mustCall((line) => {
@@ -962,13 +962,13 @@ function isWarned(emitter) {
962962

963963
// Go to the start of the line
964964
fi.emit('keypress', '.', { ctrl: true, name: 'a' });
965-
let cursorPos = rli._getCursorPos();
965+
let cursorPos = rli.getCursorPos();
966966
assert.strictEqual(cursorPos.rows, 0);
967967
assert.strictEqual(cursorPos.cols, 0);
968968

969969
// Delete right character
970970
fi.emit('keypress', '.', { ctrl: true, name: 'd' });
971-
cursorPos = rli._getCursorPos();
971+
cursorPos = rli.getCursorPos();
972972
assert.strictEqual(cursorPos.rows, 0);
973973
assert.strictEqual(cursorPos.cols, 0);
974974
rli.on('line', common.mustCall((line) => {
@@ -991,13 +991,13 @@ function isWarned(emitter) {
991991

992992
// Go to the start of the line
993993
fi.emit('keypress', '.', { ctrl: true, name: 'a' });
994-
let cursorPos = rli._getCursorPos();
994+
let cursorPos = rli.getCursorPos();
995995
assert.strictEqual(cursorPos.rows, 0);
996996
assert.strictEqual(cursorPos.cols, 0);
997997

998998
// Delete right character
999999
fi.emit('keypress', '.', { ctrl: true, name: 'd' });
1000-
cursorPos = rli._getCursorPos();
1000+
cursorPos = rli.getCursorPos();
10011001
assert.strictEqual(cursorPos.rows, 0);
10021002
assert.strictEqual(cursorPos.cols, 0);
10031003
rli.on('line', common.mustCall((line) => {
@@ -1017,13 +1017,13 @@ function isWarned(emitter) {
10171017
terminal: terminal
10181018
});
10191019
fi.emit('data', 'the quick brown fox');
1020-
let cursorPos = rli._getCursorPos();
1020+
let cursorPos = rli.getCursorPos();
10211021
assert.strictEqual(cursorPos.rows, 0);
10221022
assert.strictEqual(cursorPos.cols, 19);
10231023

10241024
// Delete from current to start of line
10251025
fi.emit('keypress', '.', { ctrl: true, shift: true, name: 'backspace' });
1026-
cursorPos = rli._getCursorPos();
1026+
cursorPos = rli.getCursorPos();
10271027
assert.strictEqual(cursorPos.rows, 0);
10281028
assert.strictEqual(cursorPos.cols, 0);
10291029
rli.on('line', common.mustCall((line) => {
@@ -1046,13 +1046,13 @@ function isWarned(emitter) {
10461046

10471047
// Go to the start of the line
10481048
fi.emit('keypress', '.', { ctrl: true, name: 'a' });
1049-
let cursorPos = rli._getCursorPos();
1049+
let cursorPos = rli.getCursorPos();
10501050
assert.strictEqual(cursorPos.rows, 0);
10511051
assert.strictEqual(cursorPos.cols, 0);
10521052

10531053
// Delete from current to end of line
10541054
fi.emit('keypress', '.', { ctrl: true, shift: true, name: 'delete' });
1055-
cursorPos = rli._getCursorPos();
1055+
cursorPos = rli.getCursorPos();
10561056
assert.strictEqual(cursorPos.rows, 0);
10571057
assert.strictEqual(cursorPos.cols, 0);
10581058
rli.on('line', common.mustCall((line) => {
@@ -1073,7 +1073,7 @@ function isWarned(emitter) {
10731073
});
10741074
fi.columns = 10;
10751075
fi.emit('data', 'multi-line text');
1076-
const cursorPos = rli._getCursorPos();
1076+
const cursorPos = rli.getCursorPos();
10771077
assert.strictEqual(cursorPos.rows, 1);
10781078
assert.strictEqual(cursorPos.cols, 5);
10791079
rli.close();
@@ -1090,7 +1090,7 @@ function isWarned(emitter) {
10901090
});
10911091
fi.columns = 10;
10921092
fi.emit('data', 't');
1093-
const cursorPos = rli._getCursorPos();
1093+
const cursorPos = rli.getCursorPos();
10941094
assert.strictEqual(cursorPos.rows, 4);
10951095
assert.strictEqual(cursorPos.cols, 3);
10961096
rli.close();
@@ -1108,7 +1108,7 @@ function isWarned(emitter) {
11081108
const lines = ['line 1', 'line 2', 'line 3'];
11091109
fi.emit('data', lines.join('\n'));
11101110
fi.emit('keypress', '.', { ctrl: true, name: 'l' });
1111-
const cursorPos = rli._getCursorPos();
1111+
const cursorPos = rli.getCursorPos();
11121112
assert.strictEqual(cursorPos.rows, 0);
11131113
assert.strictEqual(cursorPos.cols, 6);
11141114
rli.on('line', common.mustCall((line) => {

test/parallel/test-readline-position.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const ctrlU = { ctrl: true, name: 'u' };
3737

3838
for (const [cursor, string] of tests) {
3939
rl.write(string);
40-
assert.strictEqual(rl._getCursorPos().cols, cursor);
40+
assert.strictEqual(rl.getCursorPos().cols, cursor);
4141
rl.write(null, ctrlU);
4242
}
4343
}

0 commit comments

Comments
 (0)