readline: replace quadratic regex with linear one
Simplify regular expression in _wordLeft and _deleteWordLeft readline methods. PR-URL: https://github.com/nodejs/node/pull/26778 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Michaël Zasso <targos@protonmail.com>
This commit is contained in:
parent
83c35dc6e8
commit
e4e2b0ce13
@ -577,8 +577,11 @@ function commonPrefix(strings) {
|
|||||||
|
|
||||||
Interface.prototype._wordLeft = function() {
|
Interface.prototype._wordLeft = function() {
|
||||||
if (this.cursor > 0) {
|
if (this.cursor > 0) {
|
||||||
|
// Reverse the string and match a word near beginning
|
||||||
|
// to avoid quadratic time complexity
|
||||||
var leading = this.line.slice(0, this.cursor);
|
var leading = this.line.slice(0, this.cursor);
|
||||||
var match = leading.match(/(?:[^\w\s]+|\w+|)\s*$/);
|
var reversed = leading.split('').reverse().join('');
|
||||||
|
var match = reversed.match(/^\s*(?:[^\w\s]+|\w+)?/);
|
||||||
this._moveCursor(-match[0].length);
|
this._moveCursor(-match[0].length);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -634,8 +637,11 @@ Interface.prototype._deleteRight = function() {
|
|||||||
|
|
||||||
Interface.prototype._deleteWordLeft = function() {
|
Interface.prototype._deleteWordLeft = function() {
|
||||||
if (this.cursor > 0) {
|
if (this.cursor > 0) {
|
||||||
|
// Reverse the string and match a word near beginning
|
||||||
|
// to avoid quadratic time complexity
|
||||||
var leading = this.line.slice(0, this.cursor);
|
var leading = this.line.slice(0, this.cursor);
|
||||||
var match = leading.match(/(?:[^\w\s]+|\w+|)\s*$/);
|
var reversed = leading.split('').reverse().join('');
|
||||||
|
var match = reversed.match(/^\s*(?:[^\w\s]+|\w+)?/);
|
||||||
leading = leading.slice(0, leading.length - match[0].length);
|
leading = leading.slice(0, leading.length - match[0].length);
|
||||||
this.line = leading + this.line.slice(this.cursor, this.line.length);
|
this.line = leading + this.line.slice(this.cursor, this.line.length);
|
||||||
this.cursor = leading.length;
|
this.cursor = leading.length;
|
||||||
|
@ -1272,3 +1272,26 @@ const crlfDelay = Infinity;
|
|||||||
}), delay);
|
}), delay);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Ensure that the _wordLeft method works even for large input
|
||||||
|
{
|
||||||
|
const input = new Readable({
|
||||||
|
read() {
|
||||||
|
this.push('\x1B[1;5D'); // CTRL + Left
|
||||||
|
this.push(null);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const output = new Writable({
|
||||||
|
write: common.mustCall((data, encoding, cb) => {
|
||||||
|
assert.strictEqual(rl.cursor, rl.line.length - 1);
|
||||||
|
cb();
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
const rl = new readline.createInterface({
|
||||||
|
input: input,
|
||||||
|
output: output,
|
||||||
|
terminal: true,
|
||||||
|
});
|
||||||
|
rl.line = `a${' '.repeat(1e6)}a`;
|
||||||
|
rl.cursor = rl.line.length;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user