Skip to content

Commit 1ac07b2

Browse files
addaleaxdanielleadams
authored andcommitted
repl: disable blocking completions by default
It’s not okay for the REPL to be blocked for multiple seconds after entering `require('` because the completion is performing blocking fs operations on potentially huge directories. Turning the REPL completion function asynchronous would be the right thing to do here, but unfortunately the way the code is structured doesn’t play well with that (in particular, it breaks the preview feature). Therefore, disable these blocking calls by default. Refs: #33282 (comment) PR-URL: #36564 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
1 parent 8413759 commit 1ac07b2

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

lib/repl.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ const {
5858
Promise,
5959
PromiseRace,
6060
RegExp,
61+
RegExpPrototypeTest,
6162
Set,
6263
StringPrototypeCharAt,
6364
StringPrototypeIncludes,
@@ -267,6 +268,7 @@ function REPLServer(prompt,
267268
configurable: true
268269
});
269270

271+
this.allowBlockingCompletions = !!options.allowBlockingCompletions;
270272
this.useColors = !!options.useColors;
271273
this._domain = options.domain || domain.create();
272274
this.useGlobal = !!useGlobal;
@@ -1186,7 +1188,8 @@ function complete(line, callback) {
11861188
if (completeOn.length) {
11871189
filter = completeOn;
11881190
}
1189-
} else if (requireRE.test(line)) {
1191+
} else if (RegExpPrototypeTest(requireRE, line) &&
1192+
this.allowBlockingCompletions) {
11901193
// require('...<Tab>')
11911194
const extensions = ObjectKeys(this.context.require.extensions);
11921195
const indexes = extensions.map((extension) => `index${extension}`);
@@ -1244,7 +1247,8 @@ function complete(line, callback) {
12441247
if (!subdir) {
12451248
completionGroups.push(_builtinLibs);
12461249
}
1247-
} else if (fsAutoCompleteRE.test(line)) {
1250+
} else if (RegExpPrototypeTest(fsAutoCompleteRE, line) &&
1251+
this.allowBlockingCompletions) {
12481252
[completionGroups, completeOn] = completeFSFunctions(line);
12491253
// Handle variable member lookup.
12501254
// We support simple chained expressions like the following (no function

test/parallel/test-repl-tab-complete.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,12 @@ function getNoResultsFunction() {
5151

5252
const works = [['inner.one'], 'inner.o'];
5353
const putIn = new ArrayStream();
54-
const testMe = repl.start('', putIn);
54+
const testMe = repl.start({
55+
prompt: '',
56+
input: putIn,
57+
output: process.stdout,
58+
allowBlockingCompletions: true
59+
});
5560

5661
// Some errors are passed to the domain, but do not callback
5762
testMe._domain.on('error', assert.ifError);

0 commit comments

Comments
 (0)