Skip to content

Commit e8f8521

Browse files
committed
repl: improve require() autocompletion
Currently REPL supports autocompletion for core modules and those found in node_modules. This commit adds tab completion for modules relative to the current directory.
1 parent ac81267 commit e8f8521

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

lib/repl.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,18 @@ function complete(line, callback) {
794794
filter = match[1];
795795
var dir, files, f, name, base, ext, abs, subfiles, s;
796796
group = [];
797-
var paths = module.paths.concat(Module.globalPaths);
797+
let paths = [];
798+
799+
if (completeOn === '.') {
800+
group = ['./', '../'];
801+
} else if (completeOn === '..') {
802+
group = ['../'];
803+
} else if (/^\.\.?\//.test(completeOn)) {
804+
paths = [process.cwd()];
805+
} else {
806+
paths = module.paths.concat(Module.globalPaths);
807+
}
808+
798809
for (i = 0; i < paths.length; i++) {
799810
dir = path.resolve(paths[i], subdir);
800811
try {

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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,56 @@ testMe.complete('require(\'n', common.mustCall(function(error, data) {
232232
}));
233233
}
234234

235+
// Test tab completion for require() relative to the current directory
236+
{
237+
putIn.run(['.clear']);
238+
239+
const cwd = process.cwd();
240+
process.chdir(__dirname);
241+
242+
['require(\'.', 'require(".'].forEach((input) => {
243+
testMe.complete(input, common.mustCall((err, data) => {
244+
assert.strictEqual(err, null);
245+
assert.strictEqual(data.length, 2);
246+
assert.strictEqual(data[1], '.');
247+
assert.strictEqual(data[0].length, 2);
248+
assert.ok(data[0].includes('./'));
249+
assert.ok(data[0].includes('../'));
250+
}));
251+
});
252+
253+
['require(\'..', 'require("..'].forEach((input) => {
254+
testMe.complete(input, common.mustCall((err, data) => {
255+
assert.strictEqual(err, null);
256+
assert.deepStrictEqual(data, [['../'], '..']);
257+
}));
258+
});
259+
260+
['./', './test-'].forEach((path) => {
261+
[`require('${path}`, `require("${path}`].forEach((input) => {
262+
testMe.complete(input, common.mustCall((err, data) => {
263+
assert.strictEqual(err, null);
264+
assert.strictEqual(data.length, 2);
265+
assert.strictEqual(data[1], path);
266+
assert.ok(data[0].includes('./test-repl-tab-complete'));
267+
}));
268+
});
269+
});
270+
271+
['../parallel/', '../parallel/test-'].forEach((path) => {
272+
[`require('${path}`, `require("${path}`].forEach((input) => {
273+
testMe.complete(input, common.mustCall((err, data) => {
274+
assert.strictEqual(err, null);
275+
assert.strictEqual(data.length, 2);
276+
assert.strictEqual(data[1], path);
277+
assert.ok(data[0].includes('../parallel/test-repl-tab-complete'));
278+
}));
279+
});
280+
});
281+
282+
process.chdir(cwd);
283+
}
284+
235285
// Make sure tab completion works on context properties
236286
putIn.run(['.clear']);
237287

0 commit comments

Comments
 (0)