Skip to content

Commit 226b966

Browse files
ghaiklorevanlucas
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 520369d commit 226b966

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
Note that the stream, if it is a TTY, needs to be in raw mode:
366368
```js

lib/readline.js

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

4343
this._sawReturn = false;
44+
this.isCompletionEnabled = true;
4445

4546
EventEmitter.call(this);
4647
var historySize;
@@ -130,7 +131,7 @@ function Interface(input, output, completer, terminal) {
130131

131132
} else {
132133

133-
emitKeypressEvents(input);
134+
emitKeypressEvents(input, this);
134135

135136
// input usually refers to stdin
136137
input.on('keypress', onkeypress);
@@ -883,7 +884,7 @@ Interface.prototype._ttyWrite = function(s, key) {
883884

884885
case 'tab':
885886
// If tab completion enabled, do that...
886-
if (typeof this.completer === 'function') {
887+
if (typeof this.completer === 'function' && this.isCompletionEnabled) {
887888
this._tabComplete();
888889
break;
889890
}
@@ -917,7 +918,7 @@ exports.Interface = Interface;
917918
const KEYPRESS_DECODER = Symbol('keypress-decoder');
918919
const ESCAPE_DECODER = Symbol('escape-decoder');
919920

920-
function emitKeypressEvents(stream) {
921+
function emitKeypressEvents(stream, iface) {
921922
if (stream[KEYPRESS_DECODER]) return;
922923
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
923924
stream[KEYPRESS_DECODER] = new StringDecoder('utf8');
@@ -930,6 +931,10 @@ function emitKeypressEvents(stream) {
930931
var r = stream[KEYPRESS_DECODER].write(b);
931932
if (r) {
932933
for (var i = 0; i < r.length; i++) {
934+
if (r[i] === '\t' && typeof r[i + 1] === 'string' && iface) {
935+
iface.isCompletionEnabled = false;
936+
}
937+
933938
try {
934939
stream[ESCAPE_DECODER].next(r[i]);
935940
} catch (err) {
@@ -938,6 +943,10 @@ function emitKeypressEvents(stream) {
938943
stream[ESCAPE_DECODER] = emitKeys(stream);
939944
stream[ESCAPE_DECODER].next();
940945
throw err;
946+
} finally {
947+
if (iface) {
948+
iface.isCompletionEnabled = true;
949+
}
941950
}
942951
}
943952
}

test/parallel/test-readline-interface.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,9 @@ function isWarned(emitter) {
227227
assert.strictEqual(called, false);
228228
called = true;
229229
});
230-
fi.emit('data', '\tfo\to\t');
230+
for (var character of '\tfo\to\t') {
231+
fi.emit('data', character);
232+
}
231233
fi.emit('data', '\n');
232234
assert.ok(called);
233235
rli.close();

0 commit comments

Comments
 (0)