Skip to content

Commit

Permalink
readline: add getPrompt to get the current prompt
Browse files Browse the repository at this point in the history
Since there is a setPrompt() there should be a getPrompt().
There are use-cases where it is needed to know what the
current prompt is. Adding a getPrompt() negates the need
to store the set prompt externally or read the internal
_prompt which would be bad practice.

Co-authored-by: Colin Ihrig <cjihrig@gmail.com>

PR-URL: #33675
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
  • Loading branch information
mattiasrunge authored and codebytere committed Nov 22, 2020
1 parent baa87c1 commit d1baae3
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 8 deletions.
9 changes: 9 additions & 0 deletions doc/api/readline.md
Expand Up @@ -283,6 +283,15 @@ added: v0.1.98
The `rl.setPrompt()` method sets the prompt that will be written to `output`
whenever `rl.prompt()` is called.

### `rl.getPrompt()`
<!-- YAML
added: REPLACEME
-->

* Returns: {string} the current prompt string

The `rl.getPrompt()` method returns the current prompt used by `rl.prompt()`.

### `rl.write(data[, key])`
<!-- YAML
added: v0.1.98
Expand Down
12 changes: 6 additions & 6 deletions lib/internal/repl/utils.js
Expand Up @@ -144,7 +144,7 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
let escaped = null;

function getPreviewPos() {
const displayPos = repl._getDisplayPos(`${repl._prompt}${repl.line}`);
const displayPos = repl._getDisplayPos(`${repl.getPrompt()}${repl.line}`);
const cursorPos = repl.line.length !== repl.cursor ?
repl.getCursorPos() :
displayPos;
Expand Down Expand Up @@ -177,7 +177,7 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
rows = pos.displayPos.rows - pos.cursorPos.rows;
moveCursor(repl.output, 0, rows);
}
const totalLine = `${repl._prompt}${repl.line}${completionPreview}`;
const totalLine = `${repl.getPrompt()}${repl.line}${completionPreview}`;
const newPos = repl._getDisplayPos(totalLine);
// Minimize work for the terminal. It is enough to clear the right part of
// the current line in case the preview is visible on a single line.
Expand Down Expand Up @@ -263,7 +263,7 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
}
repl.output.write(result);
cursorTo(repl.output, cursorPos.cols);
const totalLine = `${repl._prompt}${repl.line}${suffix}`;
const totalLine = `${repl.getPrompt()}${repl.line}${suffix}`;
const newPos = repl._getDisplayPos(totalLine);
const rows = newPos.rows - cursorPos.rows - (newPos.cols === 0 ? 1 : 0);
moveCursor(repl.output, 0, -rows);
Expand Down Expand Up @@ -611,7 +611,7 @@ function setupReverseSearch(repl) {
let rows = 0;
if (lastMatch !== -1) {
const line = repl.history[lastMatch].slice(0, lastCursor);
rows = repl._getDisplayPos(`${repl._prompt}${line}`).rows;
rows = repl._getDisplayPos(`${repl.getPrompt()}${line}`).rows;
cursorTo(repl.output, promptPos.cols);
} else if (isInReverseSearch && repl.line !== '') {
rows = repl.getCursorPos().rows;
Expand All @@ -631,7 +631,7 @@ function setupReverseSearch(repl) {

// To know exactly how many rows we have to move the cursor back we need the
// cursor rows, the output rows and the input rows.
const prompt = repl._prompt;
const prompt = repl.getPrompt();
const cursorLine = `${prompt}${outputLine.slice(0, cursor)}`;
const cursorPos = repl._getDisplayPos(cursorLine);
const outputPos = repl._getDisplayPos(`${prompt}${outputLine}`);
Expand Down Expand Up @@ -682,7 +682,7 @@ function setupReverseSearch(repl) {
if (!isInReverseSearch) {
if (key.ctrl && checkAndSetDirectionKey(key.name)) {
historyIndex = repl.historyIndex;
promptPos = repl._getDisplayPos(`${repl._prompt}`);
promptPos = repl._getDisplayPos(`${repl.getPrompt()}`);
print(repl.line, `${labels[dir]}_`);
isInReverseSearch = true;
}
Expand Down
5 changes: 5 additions & 0 deletions lib/readline.js
Expand Up @@ -291,6 +291,11 @@ Interface.prototype.setPrompt = function(prompt) {
};


Interface.prototype.getPrompt = function() {
return this._prompt;
};


Interface.prototype._setRawMode = function(mode) {
const wasInRawMode = this.input.isRaw;

Expand Down
12 changes: 11 additions & 1 deletion test/parallel/test-readline-interface.js
Expand Up @@ -898,6 +898,16 @@ for (let i = 0; i < 12; i++) {
});
}

// Calling the getPrompt method
{
const expectedPrompts = ['$ ', '> '];
const [rli] = getInterface({ terminal });
for (const prompt of expectedPrompts) {
rli.setPrompt(prompt);
assert.strictEqual(rli.getPrompt(), prompt);
}
}

{
const expected = terminal ?
['\u001b[1G', '\u001b[0J', '$ ', '\u001b[3G'] :
Expand All @@ -920,7 +930,7 @@ for (let i = 0; i < 12; i++) {

rl.prompt();

assert.strictEqual(rl._prompt, '$ ');
assert.strictEqual(rl.getPrompt(), '$ ');
}

{
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-repl-options.js
Expand Up @@ -104,7 +104,7 @@ assert.throws(r3, {
// 4, Verify that defaults are used when no arguments are provided
const r4 = repl.start();

assert.strictEqual(r4._prompt, '> ');
assert.strictEqual(r4.getPrompt(), '> ');
assert.strictEqual(r4.input, process.stdin);
assert.strictEqual(r4.output, process.stdout);
assert.strictEqual(r4.terminal, !!r4.output.isTTY);
Expand Down

0 comments on commit d1baae3

Please sign in to comment.