Skip to content

Commit 95f332f

Browse files
Js-Brechttargos
authored andcommitted
readline: promote _getCursorPos to public api
Alias _getCursorPos() = getCursorPos() for backwards compatibility. Refs: #30347 PR-URL: #30687 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
1 parent 12e9bad commit 95f332f

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
@@ -366,7 +366,7 @@ Interface.prototype._refreshLine = function() {
366366
const lineRows = dispPos.rows;
367367

368368
// cursor position
369-
const cursorPos = this._getCursorPos();
369+
const cursorPos = this.getCursorPos();
370370

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

485-
if (this._getCursorPos().cols === 0) {
485+
if (this.getCursorPos().cols === 0) {
486486
this._refreshLine();
487487
} else {
488488
this._writeToOutput(c);
@@ -761,7 +761,7 @@ Interface.prototype._getDisplayPos = function(str) {
761761

762762

763763
// Returns current cursor's position and line
764-
Interface.prototype._getCursorPos = function() {
764+
Interface.prototype.getCursorPos = function() {
765765
const columns = this.columns;
766766
const strBeforeCursor = this._prompt + this.line.substring(0, this.cursor);
767767
const dispPos = this._getDisplayPos(
@@ -778,20 +778,21 @@ Interface.prototype._getCursorPos = function() {
778778
}
779779
return { cols: cols, rows: rows };
780780
};
781+
Interface.prototype._getCursorPos = Interface.prototype.getCursorPos;
781782

782783

783784
// This function moves cursor dx places to the right
784785
// (-dx for left) and refreshes the line if it is needed
785786
Interface.prototype._moveCursor = function(dx) {
786787
const oldcursor = this.cursor;
787-
const oldPos = this._getCursorPos();
788+
const oldPos = this.getCursorPos();
788789
this.cursor += dx;
789790

790791
// bounds check
791792
if (this.cursor < 0) this.cursor = 0;
792793
else if (this.cursor > this.line.length) this.cursor = this.line.length;
793794

794-
const newPos = this._getCursorPos();
795+
const newPos = this.getCursorPos();
795796

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

test/parallel/test-readline-interface.js

+34-34
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ function isWarned(emitter) {
570570
rli.question(expectedLines[0], function() {
571571
rli.close();
572572
});
573-
const cursorPos = rli._getCursorPos();
573+
const cursorPos = rli.getCursorPos();
574574
assert.strictEqual(cursorPos.rows, 0);
575575
assert.strictEqual(cursorPos.cols, expectedLines[0].length);
576576
rli.close();
@@ -586,7 +586,7 @@ function isWarned(emitter) {
586586
rli.question(expectedLines.join('\n'), function() {
587587
rli.close();
588588
});
589-
const cursorPos = rli._getCursorPos();
589+
const cursorPos = rli.getCursorPos();
590590
assert.strictEqual(cursorPos.rows, expectedLines.length - 1);
591591
assert.strictEqual(cursorPos.cols, expectedLines.slice(-1)[0].length);
592592
rli.close();
@@ -603,11 +603,11 @@ function isWarned(emitter) {
603603
});
604604
fi.emit('data', 'the quick brown fox');
605605
fi.emit('keypress', '.', { ctrl: true, name: 'a' });
606-
let cursorPos = rli._getCursorPos();
606+
let cursorPos = rli.getCursorPos();
607607
assert.strictEqual(cursorPos.rows, 0);
608608
assert.strictEqual(cursorPos.cols, 0);
609609
fi.emit('keypress', '.', { ctrl: true, name: 'e' });
610-
cursorPos = rli._getCursorPos();
610+
cursorPos = rli.getCursorPos();
611611
assert.strictEqual(cursorPos.rows, 0);
612612
assert.strictEqual(cursorPos.cols, 19);
613613
rli.close();
@@ -623,28 +623,28 @@ function isWarned(emitter) {
623623
terminal: terminal
624624
});
625625
fi.emit('data', 'the quick brown fox');
626-
let cursorPos = rli._getCursorPos();
626+
let cursorPos = rli.getCursorPos();
627627
assert.strictEqual(cursorPos.rows, 0);
628628
assert.strictEqual(cursorPos.cols, 19);
629629

630630
// Back one character
631631
fi.emit('keypress', '.', { ctrl: true, name: 'b' });
632-
cursorPos = rli._getCursorPos();
632+
cursorPos = rli.getCursorPos();
633633
assert.strictEqual(cursorPos.rows, 0);
634634
assert.strictEqual(cursorPos.cols, 18);
635635
// Back one character
636636
fi.emit('keypress', '.', { ctrl: true, name: 'b' });
637-
cursorPos = rli._getCursorPos();
637+
cursorPos = rli.getCursorPos();
638638
assert.strictEqual(cursorPos.rows, 0);
639639
assert.strictEqual(cursorPos.cols, 17);
640640
// Forward one character
641641
fi.emit('keypress', '.', { ctrl: true, name: 'f' });
642-
cursorPos = rli._getCursorPos();
642+
cursorPos = rli.getCursorPos();
643643
assert.strictEqual(cursorPos.rows, 0);
644644
assert.strictEqual(cursorPos.cols, 18);
645645
// Forward one character
646646
fi.emit('keypress', '.', { ctrl: true, name: 'f' });
647-
cursorPos = rli._getCursorPos();
647+
cursorPos = rli.getCursorPos();
648648
assert.strictEqual(cursorPos.rows, 0);
649649
assert.strictEqual(cursorPos.cols, 19);
650650
rli.close();
@@ -663,13 +663,13 @@ function isWarned(emitter) {
663663

664664
// Move left one character/code point
665665
fi.emit('keypress', '.', { name: 'left' });
666-
let cursorPos = rli._getCursorPos();
666+
let cursorPos = rli.getCursorPos();
667667
assert.strictEqual(cursorPos.rows, 0);
668668
assert.strictEqual(cursorPos.cols, 0);
669669

670670
// Move right one character/code point
671671
fi.emit('keypress', '.', { name: 'right' });
672-
cursorPos = rli._getCursorPos();
672+
cursorPos = rli.getCursorPos();
673673
assert.strictEqual(cursorPos.rows, 0);
674674
if (common.hasIntl) {
675675
assert.strictEqual(cursorPos.cols, 2);
@@ -697,12 +697,12 @@ function isWarned(emitter) {
697697

698698
// Move left one character/code point
699699
fi.emit('keypress', '.', { name: 'left' });
700-
let cursorPos = rli._getCursorPos();
700+
let cursorPos = rli.getCursorPos();
701701
assert.strictEqual(cursorPos.rows, 0);
702702
assert.strictEqual(cursorPos.cols, 0);
703703

704704
fi.emit('data', '🐕');
705-
cursorPos = rli._getCursorPos();
705+
cursorPos = rli.getCursorPos();
706706
assert.strictEqual(cursorPos.rows, 0);
707707

708708
if (common.hasIntl) {
@@ -733,7 +733,7 @@ function isWarned(emitter) {
733733

734734
// Move left one character/code point
735735
fi.emit('keypress', '.', { name: 'right' });
736-
let cursorPos = rli._getCursorPos();
736+
let cursorPos = rli.getCursorPos();
737737
assert.strictEqual(cursorPos.rows, 0);
738738
if (common.hasIntl) {
739739
assert.strictEqual(cursorPos.cols, 2);
@@ -744,7 +744,7 @@ function isWarned(emitter) {
744744
}
745745

746746
fi.emit('data', '🐕');
747-
cursorPos = rli._getCursorPos();
747+
cursorPos = rli.getCursorPos();
748748
assert.strictEqual(cursorPos.rows, 0);
749749
if (common.hasIntl) {
750750
assert.strictEqual(cursorPos.cols, 4);
@@ -770,19 +770,19 @@ function isWarned(emitter) {
770770
});
771771
fi.emit('data', 'the quick brown fox');
772772
fi.emit('keypress', '.', { ctrl: true, name: 'left' });
773-
let cursorPos = rli._getCursorPos();
773+
let cursorPos = rli.getCursorPos();
774774
assert.strictEqual(cursorPos.rows, 0);
775775
assert.strictEqual(cursorPos.cols, 16);
776776
fi.emit('keypress', '.', { meta: true, name: 'b' });
777-
cursorPos = rli._getCursorPos();
777+
cursorPos = rli.getCursorPos();
778778
assert.strictEqual(cursorPos.rows, 0);
779779
assert.strictEqual(cursorPos.cols, 10);
780780
fi.emit('keypress', '.', { ctrl: true, name: 'right' });
781-
cursorPos = rli._getCursorPos();
781+
cursorPos = rli.getCursorPos();
782782
assert.strictEqual(cursorPos.rows, 0);
783783
assert.strictEqual(cursorPos.cols, 16);
784784
fi.emit('keypress', '.', { meta: true, name: 'f' });
785-
cursorPos = rli._getCursorPos();
785+
cursorPos = rli.getCursorPos();
786786
assert.strictEqual(cursorPos.rows, 0);
787787
assert.strictEqual(cursorPos.cols, 19);
788788
rli.close();
@@ -884,13 +884,13 @@ function isWarned(emitter) {
884884
terminal: terminal
885885
});
886886
fi.emit('data', 'the quick brown fox');
887-
let cursorPos = rli._getCursorPos();
887+
let cursorPos = rli.getCursorPos();
888888
assert.strictEqual(cursorPos.rows, 0);
889889
assert.strictEqual(cursorPos.cols, 19);
890890

891891
// Delete left character
892892
fi.emit('keypress', '.', { ctrl: true, name: 'h' });
893-
cursorPos = rli._getCursorPos();
893+
cursorPos = rli.getCursorPos();
894894
assert.strictEqual(cursorPos.rows, 0);
895895
assert.strictEqual(cursorPos.cols, 18);
896896
rli.on('line', common.mustCall((line) => {
@@ -910,7 +910,7 @@ function isWarned(emitter) {
910910
terminal: terminal
911911
});
912912
fi.emit('data', '💻');
913-
let cursorPos = rli._getCursorPos();
913+
let cursorPos = rli.getCursorPos();
914914
assert.strictEqual(cursorPos.rows, 0);
915915
if (common.hasIntl) {
916916
assert.strictEqual(cursorPos.cols, 2);
@@ -919,7 +919,7 @@ function isWarned(emitter) {
919919
}
920920
// Delete left character
921921
fi.emit('keypress', '.', { ctrl: true, name: 'h' });
922-
cursorPos = rli._getCursorPos();
922+
cursorPos = rli.getCursorPos();
923923
assert.strictEqual(cursorPos.rows, 0);
924924
assert.strictEqual(cursorPos.cols, 0);
925925
rli.on('line', common.mustCall((line) => {
@@ -942,13 +942,13 @@ function isWarned(emitter) {
942942

943943
// Go to the start of the line
944944
fi.emit('keypress', '.', { ctrl: true, name: 'a' });
945-
let cursorPos = rli._getCursorPos();
945+
let cursorPos = rli.getCursorPos();
946946
assert.strictEqual(cursorPos.rows, 0);
947947
assert.strictEqual(cursorPos.cols, 0);
948948

949949
// Delete right character
950950
fi.emit('keypress', '.', { ctrl: true, name: 'd' });
951-
cursorPos = rli._getCursorPos();
951+
cursorPos = rli.getCursorPos();
952952
assert.strictEqual(cursorPos.rows, 0);
953953
assert.strictEqual(cursorPos.cols, 0);
954954
rli.on('line', common.mustCall((line) => {
@@ -971,13 +971,13 @@ function isWarned(emitter) {
971971

972972
// Go to the start of the line
973973
fi.emit('keypress', '.', { ctrl: true, name: 'a' });
974-
let cursorPos = rli._getCursorPos();
974+
let cursorPos = rli.getCursorPos();
975975
assert.strictEqual(cursorPos.rows, 0);
976976
assert.strictEqual(cursorPos.cols, 0);
977977

978978
// Delete right character
979979
fi.emit('keypress', '.', { ctrl: true, name: 'd' });
980-
cursorPos = rli._getCursorPos();
980+
cursorPos = rli.getCursorPos();
981981
assert.strictEqual(cursorPos.rows, 0);
982982
assert.strictEqual(cursorPos.cols, 0);
983983
rli.on('line', common.mustCall((line) => {
@@ -997,13 +997,13 @@ function isWarned(emitter) {
997997
terminal: terminal
998998
});
999999
fi.emit('data', 'the quick brown fox');
1000-
let cursorPos = rli._getCursorPos();
1000+
let cursorPos = rli.getCursorPos();
10011001
assert.strictEqual(cursorPos.rows, 0);
10021002
assert.strictEqual(cursorPos.cols, 19);
10031003

10041004
// Delete from current to start of line
10051005
fi.emit('keypress', '.', { ctrl: true, shift: true, name: 'backspace' });
1006-
cursorPos = rli._getCursorPos();
1006+
cursorPos = rli.getCursorPos();
10071007
assert.strictEqual(cursorPos.rows, 0);
10081008
assert.strictEqual(cursorPos.cols, 0);
10091009
rli.on('line', common.mustCall((line) => {
@@ -1026,13 +1026,13 @@ function isWarned(emitter) {
10261026

10271027
// Go to the start of the line
10281028
fi.emit('keypress', '.', { ctrl: true, name: 'a' });
1029-
let cursorPos = rli._getCursorPos();
1029+
let cursorPos = rli.getCursorPos();
10301030
assert.strictEqual(cursorPos.rows, 0);
10311031
assert.strictEqual(cursorPos.cols, 0);
10321032

10331033
// Delete from current to end of line
10341034
fi.emit('keypress', '.', { ctrl: true, shift: true, name: 'delete' });
1035-
cursorPos = rli._getCursorPos();
1035+
cursorPos = rli.getCursorPos();
10361036
assert.strictEqual(cursorPos.rows, 0);
10371037
assert.strictEqual(cursorPos.cols, 0);
10381038
rli.on('line', common.mustCall((line) => {
@@ -1053,7 +1053,7 @@ function isWarned(emitter) {
10531053
});
10541054
fi.columns = 10;
10551055
fi.emit('data', 'multi-line text');
1056-
const cursorPos = rli._getCursorPos();
1056+
const cursorPos = rli.getCursorPos();
10571057
assert.strictEqual(cursorPos.rows, 1);
10581058
assert.strictEqual(cursorPos.cols, 5);
10591059
rli.close();
@@ -1070,7 +1070,7 @@ function isWarned(emitter) {
10701070
});
10711071
fi.columns = 10;
10721072
fi.emit('data', 't');
1073-
const cursorPos = rli._getCursorPos();
1073+
const cursorPos = rli.getCursorPos();
10741074
assert.strictEqual(cursorPos.rows, 4);
10751075
assert.strictEqual(cursorPos.cols, 3);
10761076
rli.close();
@@ -1088,7 +1088,7 @@ function isWarned(emitter) {
10881088
const lines = ['line 1', 'line 2', 'line 3'];
10891089
fi.emit('data', lines.join('\n'));
10901090
fi.emit('keypress', '.', { ctrl: true, name: 'l' });
1091-
const cursorPos = rli._getCursorPos();
1091+
const cursorPos = rli.getCursorPos();
10921092
assert.strictEqual(cursorPos.rows, 0);
10931093
assert.strictEqual(cursorPos.cols, 6);
10941094
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)