summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAntoine du Hamel <duhamelantoine1995@gmail.com>2020-11-15 23:28:06 +0100
committerNode.js GitHub Bot <github-bot@iojs.org>2020-12-04 18:34:32 +0000
commited6e71a1ca68db49a44ce5e468ec13adbff451df (patch)
treebcaea40c2da7982253261b3f38197d02680452f6 /lib
parente074bee7da4941dac9e688bbdb328e167589e0e7 (diff)
downloadios-node-v8-ed6e71a1ca68db49a44ce5e468ec13adbff451df.tar.gz
ios-node-v8-ed6e71a1ca68db49a44ce5e468ec13adbff451df.tar.bz2
ios-node-v8-ed6e71a1ca68db49a44ce5e468ec13adbff451df.zip
readline: refactor to use more primordials
PR-URL: https://github.com/nodejs/node/pull/36296 Reviewed-By: Rich Trott <rtrott@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/internal/readline/utils.js37
-rw-r--r--lib/readline.js119
2 files changed, 99 insertions, 57 deletions
diff --git a/lib/internal/readline/utils.js b/lib/internal/readline/utils.js
index cce4045a5a..55b3e07b4c 100644
--- a/lib/internal/readline/utils.js
+++ b/lib/internal/readline/utils.js
@@ -1,7 +1,15 @@
'use strict';
const {
+ ArrayPrototypeSlice,
+ ArrayPrototypeSort,
+ RegExpPrototypeTest,
StringFromCharCode,
+ StringPrototypeCharCodeAt,
+ StringPrototypeCodePointAt,
+ StringPrototypeMatch,
+ StringPrototypeSlice,
+ StringPrototypeToLowerCase,
Symbol,
} = primordials;
@@ -32,8 +40,9 @@ CSI.kClearScreenDown = CSI`0J`;
function charLengthLeft(str, i) {
if (i <= 0)
return 0;
- if ((i > 1 && str.codePointAt(i - 2) >= kUTF16SurrogateThreshold) ||
- str.codePointAt(i - 1) >= kUTF16SurrogateThreshold) {
+ if ((i > 1 &&
+ StringPrototypeCodePointAt(str, i - 2) >= kUTF16SurrogateThreshold) ||
+ StringPrototypeCodePointAt(str, i - 1) >= kUTF16SurrogateThreshold) {
return 2;
}
return 1;
@@ -45,7 +54,7 @@ function charLengthAt(str, i) {
// moving to the right.
return 1;
}
- return str.codePointAt(i) >= kUTF16SurrogateThreshold ? 2 : 1;
+ return StringPrototypeCodePointAt(str, i) >= kUTF16SurrogateThreshold ? 2 : 1;
}
/*
@@ -178,13 +187,15 @@ function* emitKeys(stream) {
* We buffered enough data, now trying to extract code
* and modifier from it
*/
- const cmd = s.slice(cmdStart);
+ const cmd = StringPrototypeSlice(s, cmdStart);
let match;
- if ((match = cmd.match(/^(\d\d?)(;(\d))?([~^$])$/))) {
+ if ((match = StringPrototypeMatch(cmd, /^(\d\d?)(;(\d))?([~^$])$/))) {
code += match[1] + match[4];
modifier = (match[3] || 1) - 1;
- } else if ((match = cmd.match(/^((\d;)?(\d))?([A-Za-z])$/))) {
+ } else if (
+ (match = StringPrototypeMatch(cmd, /^((\d;)?(\d))?([A-Za-z])$/))
+ ) {
code += match[4];
modifier = (match[3] || 1) - 1;
} else {
@@ -325,12 +336,14 @@ function* emitKeys(stream) {
key.meta = escaped;
} else if (!escaped && ch <= '\x1a') {
// ctrl+letter
- key.name = StringFromCharCode(ch.charCodeAt(0) + 'a'.charCodeAt(0) - 1);
+ key.name = StringFromCharCode(
+ StringPrototypeCharCodeAt(ch) + StringPrototypeCharCodeAt('a') - 1
+ );
key.ctrl = true;
- } else if (/^[0-9A-Za-z]$/.test(ch)) {
+ } else if (RegExpPrototypeTest(/^[0-9A-Za-z]$/, ch)) {
// Letter, number, shift+letter
- key.name = ch.toLowerCase();
- key.shift = /^[A-Z]$/.test(ch);
+ key.name = StringPrototypeToLowerCase(ch);
+ key.shift = RegExpPrototypeTest(/^[A-Z]$/, ch);
key.meta = escaped;
} else if (escaped) {
// Escape sequence timeout
@@ -356,12 +369,12 @@ function commonPrefix(strings) {
if (strings.length === 1) {
return strings[0];
}
- const sorted = strings.slice().sort();
+ const sorted = ArrayPrototypeSort(ArrayPrototypeSlice(strings));
const min = sorted[0];
const max = sorted[sorted.length - 1];
for (let i = 0; i < min.length; i++) {
if (min[i] !== max[i]) {
- return min.slice(0, i);
+ return StringPrototypeSlice(min, 0, i);
}
}
return min;
diff --git a/lib/readline.js b/lib/readline.js
index f8330a1e16..d2fd9924b0 100644
--- a/lib/readline.js
+++ b/lib/readline.js
@@ -28,7 +28,18 @@
'use strict';
const {
+ ArrayFrom,
+ ArrayPrototypeFilter,
+ ArrayPrototypeIndexOf,
+ ArrayPrototypeJoin,
+ ArrayPrototypeMap,
+ ArrayPrototypePop,
+ ArrayPrototypeReverse,
+ ArrayPrototypeSplice,
+ ArrayPrototypeUnshift,
DateNow,
+ FunctionPrototypeBind,
+ FunctionPrototypeCall,
MathCeil,
MathFloor,
MathMax,
@@ -36,6 +47,16 @@ const {
NumberIsNaN,
ObjectDefineProperty,
ObjectSetPrototypeOf,
+ RegExpPrototypeTest,
+ StringPrototypeCodePointAt,
+ StringPrototypeEndsWith,
+ StringPrototypeMatch,
+ StringPrototypeRepeat,
+ StringPrototypeReplace,
+ StringPrototypeSlice,
+ StringPrototypeSplit,
+ StringPrototypeStartsWith,
+ StringPrototypeTrim,
Symbol,
SymbolAsyncIterator,
} = primordials;
@@ -110,7 +131,7 @@ function Interface(input, output, completer, terminal) {
this.escapeCodeTimeout = ESCAPE_CODE_TIMEOUT;
this.tabSize = 8;
- EventEmitter.call(this);
+ FunctionPrototypeCall(EventEmitter, this,);
let historySize;
let removeHistoryDuplicates = false;
let crlfDelay;
@@ -187,7 +208,7 @@ function Interface(input, output, completer, terminal) {
this.terminal = !!terminal;
if (process.env.TERM === 'dumb') {
- this._ttyWrite = _ttyWriteDumb.bind(this);
+ this._ttyWrite = FunctionPrototypeBind(_ttyWriteDumb, this);
}
function onerror(err) {
@@ -219,7 +240,7 @@ function Interface(input, output, completer, terminal) {
// If the key.sequence is half of a surrogate pair
// (>= 0xd800 and <= 0xdfff), refresh the line so
// the character is displayed appropriately.
- const ch = key.sequence.codePointAt(0);
+ const ch = StringPrototypeCodePointAt(key.sequence, 0);
if (ch >= 0xd800 && ch <= 0xdfff)
self._refreshLine();
}
@@ -366,19 +387,19 @@ Interface.prototype._addHistory = function() {
if (this.historySize === 0) return this.line;
// If the trimmed line is empty then return the line
- if (this.line.trim().length === 0) return this.line;
+ if (StringPrototypeTrim(this.line).length === 0) return this.line;
if (this.history.length === 0 || this.history[0] !== this.line) {
if (this.removeHistoryDuplicates) {
// Remove older history line if identical to new one
- const dupIndex = this.history.indexOf(this.line);
- if (dupIndex !== -1) this.history.splice(dupIndex, 1);
+ const dupIndex = ArrayPrototypeIndexOf(this.history, this.line);
+ if (dupIndex !== -1) ArrayPrototypeSplice(this.history, dupIndex, 1);
}
- this.history.unshift(this.line);
+ ArrayPrototypeUnshift(this.history, this.line);
// Only store so many
- if (this.history.length > this.historySize) this.history.pop();
+ if (this.history.length > this.historySize) ArrayPrototypePop(this.history);
}
this.historyIndex = -1;
@@ -472,24 +493,24 @@ Interface.prototype._normalWrite = function(b) {
let string = this._decoder.write(b);
if (this._sawReturnAt &&
DateNow() - this._sawReturnAt <= this.crlfDelay) {
- string = string.replace(/^\n/, '');
+ string = StringPrototypeReplace(string, /^\n/, '');
this._sawReturnAt = 0;
}
// Run test() on the new string chunk, not on the entire line buffer.
- const newPartContainsEnding = lineEnding.test(string);
+ const newPartContainsEnding = RegExpPrototypeTest(lineEnding, string);
if (this._line_buffer) {
string = this._line_buffer + string;
this._line_buffer = null;
}
if (newPartContainsEnding) {
- this._sawReturnAt = string.endsWith('\r') ? DateNow() : 0;
+ this._sawReturnAt = StringPrototypeEndsWith(string, '\r') ? DateNow() : 0;
// Got one or more newlines; process into "line" events
- const lines = string.split(lineEnding);
+ const lines = StringPrototypeSplit(string, lineEnding);
// Either '' or (conceivably) the unfinished portion of the next line
- string = lines.pop();
+ string = ArrayPrototypePop(lines);
this._line_buffer = string;
for (let n = 0; n < lines.length; n++)
this._onLine(lines[n]);
@@ -501,8 +522,8 @@ Interface.prototype._normalWrite = function(b) {
Interface.prototype._insertString = function(c) {
if (this.cursor < this.line.length) {
- const beg = this.line.slice(0, this.cursor);
- const end = this.line.slice(this.cursor, this.line.length);
+ const beg = StringPrototypeSlice(this.line, 0, this.cursor);
+ const end = StringPrototypeSlice(this.line, this.cursor, this.line.length);
this.line = beg + c + end;
this.cursor += c.length;
this._refreshLine();
@@ -520,7 +541,8 @@ Interface.prototype._insertString = function(c) {
Interface.prototype._tabComplete = function(lastKeypressWasTab) {
this.pause();
- this.completer(this.line.slice(0, this.cursor), (err, value) => {
+ const string = StringPrototypeSlice(this.line, 0, this.cursor);
+ this.completer(string, (err, value) => {
this.resume();
if (err) {
@@ -536,9 +558,10 @@ Interface.prototype._tabComplete = function(lastKeypressWasTab) {
}
// If there is a common prefix to all matches, then apply that portion.
- const prefix = commonPrefix(completions.filter((e) => e !== ''));
+ const prefix = commonPrefix(ArrayPrototypeFilter(completions,
+ (e) => e !== ''));
if (prefix.length > completeOn.length) {
- this._insertString(prefix.slice(completeOn.length));
+ this._insertString(StringPrototypeSlice(prefix, completeOn.length));
return;
}
@@ -547,7 +570,8 @@ Interface.prototype._tabComplete = function(lastKeypressWasTab) {
}
// Apply/show completions.
- const completionsWidth = completions.map((e) => getStringWidth(e));
+ const completionsWidth = ArrayPrototypeMap(completions,
+ (e) => getStringWidth(e));
const width = MathMax(...completionsWidth) + 2; // 2 space padding
let maxColumns = MathFloor(this.columns / width) || 1;
if (maxColumns === Infinity) {
@@ -563,7 +587,7 @@ Interface.prototype._tabComplete = function(lastKeypressWasTab) {
lineIndex = 0;
whitespace = 0;
} else {
- output += ' '.repeat(whitespace);
+ output += StringPrototypeRepeat(' ', whitespace);
}
if (completion !== '') {
output += completion;
@@ -585,9 +609,10 @@ Interface.prototype._wordLeft = function() {
if (this.cursor > 0) {
// Reverse the string and match a word near beginning
// to avoid quadratic time complexity
- const leading = this.line.slice(0, this.cursor);
- const reversed = leading.split('').reverse().join('');
- const match = reversed.match(/^\s*(?:[^\w\s]+|\w+)?/);
+ const leading = StringPrototypeSlice(this.line, 0, this.cursor);
+ const reversed = ArrayPrototypeJoin(
+ ArrayPrototypeReverse(ArrayFrom(leading)), '');
+ const match = StringPrototypeMatch(reversed, /^\s*(?:[^\w\s]+|\w+)?/);
this._moveCursor(-match[0].length);
}
};
@@ -595,8 +620,8 @@ Interface.prototype._wordLeft = function() {
Interface.prototype._wordRight = function() {
if (this.cursor < this.line.length) {
- const trailing = this.line.slice(this.cursor);
- const match = trailing.match(/^(?:\s+|[^\w\s]+|\w+)\s*/);
+ const trailing = StringPrototypeSlice(this.line, this.cursor);
+ const match = StringPrototypeMatch(trailing, /^(?:\s+|[^\w\s]+|\w+)\s*/);
this._moveCursor(match[0].length);
}
};
@@ -605,8 +630,8 @@ Interface.prototype._deleteLeft = function() {
if (this.cursor > 0 && this.line.length > 0) {
// The number of UTF-16 units comprising the character to the left
const charSize = charLengthLeft(this.line, this.cursor);
- this.line = this.line.slice(0, this.cursor - charSize) +
- this.line.slice(this.cursor, this.line.length);
+ this.line = StringPrototypeSlice(this.line, 0, this.cursor - charSize) +
+ StringPrototypeSlice(this.line, this.cursor, this.line.length);
this.cursor -= charSize;
this._refreshLine();
@@ -618,8 +643,8 @@ Interface.prototype._deleteRight = function() {
if (this.cursor < this.line.length) {
// The number of UTF-16 units comprising the character to the left
const charSize = charLengthAt(this.line, this.cursor);
- this.line = this.line.slice(0, this.cursor) +
- this.line.slice(this.cursor + charSize, this.line.length);
+ this.line = StringPrototypeSlice(this.line, 0, this.cursor) +
+ StringPrototypeSlice(this.line, this.cursor + charSize, this.line.length);
this._refreshLine();
}
};
@@ -629,11 +654,14 @@ Interface.prototype._deleteWordLeft = function() {
if (this.cursor > 0) {
// Reverse the string and match a word near beginning
// to avoid quadratic time complexity
- let leading = this.line.slice(0, this.cursor);
- const reversed = leading.split('').reverse().join('');
- const match = reversed.match(/^\s*(?:[^\w\s]+|\w+)?/);
- leading = leading.slice(0, leading.length - match[0].length);
- this.line = leading + this.line.slice(this.cursor, this.line.length);
+ let leading = StringPrototypeSlice(this.line, 0, this.cursor);
+ const reversed = ArrayPrototypeJoin(
+ ArrayPrototypeReverse(ArrayFrom(leading)), '');
+ const match = StringPrototypeMatch(reversed, /^\s*(?:[^\w\s]+|\w+)?/);
+ leading = StringPrototypeSlice(leading, 0,
+ leading.length - match[0].length);
+ this.line = leading + StringPrototypeSlice(this.line, this.cursor,
+ this.line.length);
this.cursor = leading.length;
this._refreshLine();
}
@@ -642,24 +670,24 @@ Interface.prototype._deleteWordLeft = function() {
Interface.prototype._deleteWordRight = function() {
if (this.cursor < this.line.length) {
- const trailing = this.line.slice(this.cursor);
- const match = trailing.match(/^(?:\s+|\W+|\w+)\s*/);
- this.line = this.line.slice(0, this.cursor) +
- trailing.slice(match[0].length);
+ const trailing = StringPrototypeSlice(this.line, this.cursor);
+ const match = StringPrototypeMatch(trailing, /^(?:\s+|\W+|\w+)\s*/);
+ this.line = StringPrototypeSlice(this.line, 0, this.cursor) +
+ StringPrototypeSlice(trailing, match[0].length);
this._refreshLine();
}
};
Interface.prototype._deleteLineLeft = function() {
- this.line = this.line.slice(this.cursor);
+ this.line = StringPrototypeSlice(this.line, this.cursor);
this.cursor = 0;
this._refreshLine();
};
Interface.prototype._deleteLineRight = function() {
- this.line = this.line.slice(0, this.cursor);
+ this.line = StringPrototypeSlice(this.line, 0, this.cursor);
this._refreshLine();
};
@@ -691,7 +719,7 @@ Interface.prototype._historyNext = function() {
const search = this[kSubstringSearch] || '';
let index = this.historyIndex - 1;
while (index >= 0 &&
- (!this.history[index].startsWith(search) ||
+ (!StringPrototypeStartsWith(this.history[index], search) ||
this.line === this.history[index])) {
index--;
}
@@ -711,7 +739,7 @@ Interface.prototype._historyPrev = function() {
const search = this[kSubstringSearch] || '';
let index = this.historyIndex + 1;
while (index < this.history.length &&
- (!this.history[index].startsWith(search) ||
+ (!StringPrototypeStartsWith(this.history[index], search) ||
this.line === this.history[index])) {
index++;
}
@@ -761,7 +789,8 @@ Interface.prototype._getDisplayPos = function(str) {
// Returns current cursor's position and line
Interface.prototype.getCursorPos = function() {
- const strBeforeCursor = this._prompt + this.line.substring(0, this.cursor);
+ const strBeforeCursor = this._prompt +
+ StringPrototypeSlice(this.line, 0, this.cursor);
return this._getDisplayPos(strBeforeCursor);
};
Interface.prototype._getCursorPos = Interface.prototype.getCursorPos;
@@ -851,7 +880,7 @@ Interface.prototype._ttyWrite = function(s, key) {
if ((key.name === 'up' || key.name === 'down') &&
!key.ctrl && !key.meta && !key.shift) {
if (this[kSubstringSearch] === null) {
- this[kSubstringSearch] = this.line.slice(0, this.cursor);
+ this[kSubstringSearch] = StringPrototypeSlice(this.line, 0, this.cursor);
}
} else if (this[kSubstringSearch] !== null) {
this[kSubstringSearch] = null;
@@ -1075,7 +1104,7 @@ Interface.prototype._ttyWrite = function(s, key) {
// falls through
default:
if (typeof s === 'string' && s) {
- const lines = s.split(/\r\n|\n|\r/);
+ const lines = StringPrototypeSplit(s, /\r\n|\n|\r/);
for (let i = 0, len = lines.length; i < len; i++) {
if (i > 0) {
this._line();