Skip to content

Commit 5f9b8f1

Browse files
committed
repl: do not use the custom parser but split lines with \r
1 parent 83324e0 commit 5f9b8f1

9 files changed

+124
-405
lines changed

benchmark/repl/parse-history-from-file.js

-97
This file was deleted.

lib/internal/readline/interface.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const {
2525
StringPrototypeCodePointAt,
2626
StringPrototypeEndsWith,
2727
StringPrototypeRepeat,
28+
StringPrototypeReplaceAll,
2829
StringPrototypeSlice,
2930
StringPrototypeStartsWith,
3031
StringPrototypeTrim,
@@ -950,7 +951,7 @@ class Interface extends InterfaceConstructor {
950951
if (index === -1) {
951952
this.line = search;
952953
} else {
953-
this.line = this.history[index];
954+
this.line = StringPrototypeReplaceAll(this.history[index], '\r', '\n');
954955
}
955956
this.historyIndex = index;
956957
this.cursor = this.line.length; // Set cursor to end of line.
@@ -973,7 +974,7 @@ class Interface extends InterfaceConstructor {
973974
if (index === this.history.length) {
974975
this.line = search;
975976
} else {
976-
this.line = this.history[index];
977+
this.line = StringPrototypeReplaceAll(this.history[index], '\r', '\n');
977978
}
978979
this.historyIndex = index;
979980
this.cursor = this.line.length; // Set cursor to end of line.

lib/internal/repl/history-utils.js

-77
This file was deleted.

lib/internal/repl/history.js

+3-21
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22

33
const {
44
ArrayPrototypeJoin,
5-
ArrayPrototypePush,
65
Boolean,
76
FunctionPrototype,
8-
StringPrototypeSplit,
7+
RegExpPrototypeSymbolSplit,
98
StringPrototypeTrim,
109
} = primordials;
1110

@@ -18,7 +17,6 @@ let debug = require('internal/util/debuglog').debuglog('repl', (fn) => {
1817
});
1918
const permission = require('internal/process/permission');
2019
const { clearTimeout, setTimeout } = require('timers');
21-
const { parseHistoryFromFile } = require('internal/repl/history-utils');
2220

2321
const noop = FunctionPrototype;
2422

@@ -99,7 +97,7 @@ function setupHistory(repl, historyPath, ready) {
9997
}
10098

10199
if (data) {
102-
repl.history = parseHistoryFromFile(data, repl.historySize);
100+
repl.history = RegExpPrototypeSymbolSplit(/[\n]+/, data, repl.historySize);
103101
} else {
104102
repl.history = [];
105103
}
@@ -136,30 +134,14 @@ function setupHistory(repl, historyPath, ready) {
136134
timer = setTimeout(flushHistory, kDebounceHistoryMS);
137135
}
138136

139-
function parseHistoryData() {
140-
const eol = os.EOL;
141-
const result = [];
142-
const historyLength = repl.history.length;
143-
144-
for (let i = 0; i < historyLength; i++) {
145-
const entry = repl.history[i];
146-
const lines = StringPrototypeSplit(entry, eol);
147-
for (let j = lines.length - 1; j >= 0; j--) {
148-
ArrayPrototypePush(result, lines[j]);
149-
}
150-
}
151-
152-
return ArrayPrototypeJoin(result, eol) + eol;
153-
}
154-
155137
function flushHistory() {
156138
timer = null;
157139
if (writing) {
158140
pending = true;
159141
return;
160142
}
161143
writing = true;
162-
const historyData = parseHistoryData();
144+
const historyData = ArrayPrototypeJoin(repl.history, os.EOL);
163145
fs.write(repl._historyHandle, historyData, 0, 'utf8', onwritten);
164146
}
165147

lib/repl.js

+14-5
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ const {
8383
StringPrototypeCodePointAt,
8484
StringPrototypeEndsWith,
8585
StringPrototypeIncludes,
86+
StringPrototypeIndexOf,
8687
StringPrototypeRepeat,
88+
StringPrototypeReplaceAll,
8789
StringPrototypeSlice,
8890
StringPrototypeSplit,
8991
StringPrototypeStartsWith,
@@ -117,7 +119,6 @@ const {
117119
} = require('internal/util');
118120
const { inspect } = require('internal/util/inspect');
119121
const vm = require('vm');
120-
const os = require('os');
121122

122123
const { runInThisContext, runInContext } = vm.Script.prototype;
123124

@@ -953,14 +954,22 @@ function REPLServer(prompt,
953954
self._domain.emit('error', e.err || e);
954955
}
955956

956-
if (self[kBufferedCommandSymbol]) {
957+
// In the next two if blocks, we do not use os.EOL instead of '\n'
958+
// because on Windows it is '\r\n'
959+
if (cmd && StringPrototypeIndexOf(cmd, '\n') !== -1) { // If you are editing a multiline command
960+
self.history[0] = StringPrototypeReplaceAll(cmd, '\n', '\r');
961+
} else if (self[kBufferedCommandSymbol]) { // If a new multiline command was entered
957962
// Remove the first N lines from the self.history array
958963
// where N is the number of lines in the buffered command
959-
const lines = StringPrototypeSplit(self[kBufferedCommandSymbol], os.EOL);
964+
965+
const lines = StringPrototypeSplit(self[kBufferedCommandSymbol], '\n');
960966
self.history = ArrayPrototypeSlice(self.history, lines.length);
961-
// And replace them with the single command divided into lines
962-
ArrayPrototypeUnshift(self.history, self[kBufferedCommandSymbol] + cmd);
967+
ArrayPrototypePop(lines);
968+
// And replace them with the single command split by '\r'
969+
ArrayPrototypePush(lines, cmd);
970+
ArrayPrototypeUnshift(self.history, ArrayPrototypeJoin(lines, '\r'));
963971
}
972+
964973
// Clear buffer if no SyntaxErrors
965974
self.clearBufferedCommand();
966975
sawCtrlD = false;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
var d = [^M {^M a: 1,^M b: 2,^M },^M {^M a: 3,^M b: 4,^M c: [{ a: 1, b: 2 },^M {^M a: 3,^M b: 4,^M }^M ]^M }^M]
2+
const c = [^M {^M a: 1,^M b: 2,^M }^M]
3+
`const b = [^M 1,^M 2,^M 3,^M 4,^M]`
4+
a = `^MI am a multiline string^MI can be as long as I want`

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

+11-16
Original file line numberDiff line numberDiff line change
@@ -236,22 +236,17 @@ const tests = [
236236
// K = Erase in line; 0 = right; 1 = left; 2 = total
237237
expected: [
238238
// 0. Start
239-
'\x1B[1G',
240-
'\x1B[0J',
241-
`${prompt}`,
242-
'\x1B[3G',
243-
'\x1B[1G',
244-
'\x1B[0J',
245-
`${prompt}aut`,
246-
'\x1B[6G',
247-
' // ocompleteMe',
248-
'\x1B[6G',
249-
'\n// 123',
250-
'\x1B[6G',
251-
'\x1B[1A',
252-
'\x1B[1B',
253-
'\x1B[2K',
254-
'\x1B[1A',
239+
'\x1B[1G', '\x1B[0J',
240+
prompt, '\x1B[3G',
241+
// 1. UP
242+
// This exceeds the maximum columns (250):
243+
// Whitespace + prompt + ' // '.length + 'autocompleteMe'.length
244+
// 230 + 2 + 4 + 14
245+
'\x1B[1G', '\x1B[0J',
246+
`${prompt}${' '.repeat(230)} aut`, '\x1B[237G',
247+
' // ocompleteMe', '\x1B[237G',
248+
'\n// 123', '\x1B[237G',
249+
'\x1B[1A', '\x1B[1B', '\x1B[2K', '\x1B[1A',
255250
'\x1B[0K',
256251
// 2. UP
257252
'\x1B[1G', '\x1B[0J',

0 commit comments

Comments
 (0)