Skip to content

Commit ae17883

Browse files
ghaikloraddaleax
authored andcommitted
repl: copying tabs shouldn't trigger completion
PR-URL: #5958 Fixes: #5954 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]>
1 parent 830a726 commit ae17883

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

doc/api/readline.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,10 +357,12 @@ a `'resize'` event on the `output` if/when the columns ever change
357357

358358
Move cursor to the specified position in a given TTY stream.
359359

360-
## readline.emitKeypressEvents(stream)
360+
## readline.emitKeypressEvents(stream[, interface])
361361

362362
Causes `stream` to begin emitting `'keypress'` events corresponding to its
363363
input.
364+
Optionally, `interface` specifies a `readline.Interface` instance for which
365+
autocompletion is disabled when copy-pasted input is detected.
364366

365367
## readline.moveCursor(stream, dx, dy)
366368

lib/readline.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ function Interface(input, output, completer, terminal) {
4040
}
4141

4242
this._sawReturn = false;
43+
this.isCompletionEnabled = true;
4344

4445
EventEmitter.call(this);
4546
var historySize;
@@ -129,7 +130,7 @@ function Interface(input, output, completer, terminal) {
129130

130131
} else {
131132

132-
emitKeypressEvents(input);
133+
emitKeypressEvents(input, this);
133134

134135
// input usually refers to stdin
135136
input.on('keypress', onkeypress);
@@ -878,7 +879,7 @@ Interface.prototype._ttyWrite = function(s, key) {
878879

879880
case 'tab':
880881
// If tab completion enabled, do that...
881-
if (typeof this.completer === 'function') {
882+
if (typeof this.completer === 'function' && this.isCompletionEnabled) {
882883
this._tabComplete();
883884
break;
884885
}
@@ -912,7 +913,7 @@ exports.Interface = Interface;
912913
const KEYPRESS_DECODER = Symbol('keypress-decoder');
913914
const ESCAPE_DECODER = Symbol('escape-decoder');
914915

915-
function emitKeypressEvents(stream) {
916+
function emitKeypressEvents(stream, iface) {
916917
if (stream[KEYPRESS_DECODER]) return;
917918
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
918919
stream[KEYPRESS_DECODER] = new StringDecoder('utf8');
@@ -925,6 +926,10 @@ function emitKeypressEvents(stream) {
925926
var r = stream[KEYPRESS_DECODER].write(b);
926927
if (r) {
927928
for (var i = 0; i < r.length; i++) {
929+
if (r[i] === '\t' && typeof r[i + 1] === 'string' && iface) {
930+
iface.isCompletionEnabled = false;
931+
}
932+
928933
try {
929934
stream[ESCAPE_DECODER].next(r[i]);
930935
} catch (err) {
@@ -933,6 +938,10 @@ function emitKeypressEvents(stream) {
933938
stream[ESCAPE_DECODER] = emitKeys(stream);
934939
stream[ESCAPE_DECODER].next();
935940
throw err;
941+
} finally {
942+
if (iface) {
943+
iface.isCompletionEnabled = true;
944+
}
936945
}
937946
}
938947
}

test/parallel/test-readline-interface.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,9 @@ function isWarned(emitter) {
229229
assert.strictEqual(called, false);
230230
called = true;
231231
});
232-
fi.emit('data', '\tfo\to\t');
232+
for (var character of '\tfo\to\t') {
233+
fi.emit('data', character);
234+
}
233235
fi.emit('data', '\n');
234236
assert.ok(called);
235237
rli.close();

0 commit comments

Comments
 (0)