Skip to content

Commit b3f3ebf

Browse files
antsmartiantargos
authored andcommitted
lib: repl multiline history support
PR-URL: #22153 Reviewed-By: John-David Dalton <john.david.dalton@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 2331181 commit b3f3ebf

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

lib/readline.js

+25
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ function Interface(input, output, completer, terminal) {
217217

218218
// Current line
219219
this.line = '';
220+
this.multiline = '';
220221

221222
this._setRawMode(true);
222223
this.terminal = true;
@@ -327,6 +328,7 @@ Interface.prototype._addHistory = function() {
327328
if (dupIndex !== -1) this.history.splice(dupIndex, 1);
328329
}
329330

331+
this.multiline += this.line;
330332
this.history.unshift(this.line);
331333

332334
// Only store so many
@@ -337,6 +339,29 @@ Interface.prototype._addHistory = function() {
337339
return this.history[0];
338340
};
339341

342+
// Called when a multiline is seen by the repl
343+
Interface.prototype.undoHistory = function() {
344+
if (this.terminal) {
345+
this.history.shift();
346+
}
347+
};
348+
349+
// If it's a multiline code, then add history
350+
// accordingly.
351+
Interface.prototype.multilineHistory = function() {
352+
// check if we got a multiline code
353+
if (this.multiline !== '' && this.terminal) {
354+
const dupIndex = this.history.indexOf(this.multiline);
355+
if (dupIndex !== -1) this.history.splice(dupIndex, 1);
356+
// Remove the last entered line as multiline
357+
// already contains them.
358+
this.history.shift();
359+
this.history.unshift(this.multiline);
360+
}
361+
362+
// clear the multiline buffer
363+
this.multiline = '';
364+
};
340365

341366
Interface.prototype._refreshLine = function() {
342367
// line length

lib/repl.js

+2
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,7 @@ exports.start = function(prompt,
779779

780780
REPLServer.prototype.clearBufferedCommand = function clearBufferedCommand() {
781781
this[kBufferedCommandSymbol] = '';
782+
REPLServer.super_.prototype.multilineHistory.call(this);
782783
};
783784

784785
REPLServer.prototype.close = function close() {
@@ -893,6 +894,7 @@ REPLServer.prototype.displayPrompt = function(preserveCursor) {
893894
const len = this.lines.level.length ? this.lines.level.length - 1 : 0;
894895
const levelInd = '..'.repeat(len);
895896
prompt += levelInd + ' ';
897+
REPLServer.super_.prototype.undoHistory.call(this);
896898
}
897899

898900
// Do not overwrite `_initialPrompt` here

test/parallel/test-repl-persistent-history.js

+7
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ const tests = [
111111
test: [UP],
112112
expected: [prompt, replFailedRead, prompt, replDisabled, prompt]
113113
},
114+
{ // Tests multiline history
115+
env: {},
116+
test: ['{', '}', UP, CLEAR],
117+
expected: [prompt, '{', '... ', '}', '{}\n',
118+
prompt, `${prompt}{}`, prompt],
119+
clean: false
120+
},
114121
{
115122
before: function before() {
116123
if (common.isWindows) {

0 commit comments

Comments
 (0)