diff --git a/lib/repl.js b/lib/repl.js index 79abb35ce289de..41e630488dcd12 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -794,7 +794,18 @@ function complete(line, callback) { filter = match[1]; var dir, files, f, name, base, ext, abs, subfiles, s; group = []; - var paths = module.paths.concat(Module.globalPaths); + let paths = []; + + if (completeOn === '.') { + group = ['./', '../']; + } else if (completeOn === '..') { + group = ['../']; + } else if (/^\.\.?\//.test(completeOn)) { + paths = [process.cwd()]; + } else { + paths = module.paths.concat(Module.globalPaths); + } + for (i = 0; i < paths.length; i++) { dir = path.resolve(paths[i], subdir); try { diff --git a/test/parallel/test-repl-tab-complete.js b/test/parallel/test-repl-tab-complete.js index cf67e920f9528d..994421ffc58a6a 100644 --- a/test/parallel/test-repl-tab-complete.js +++ b/test/parallel/test-repl-tab-complete.js @@ -232,6 +232,56 @@ testMe.complete('require(\'n', common.mustCall(function(error, data) { })); } +// Test tab completion for require() relative to the current directory +{ + putIn.run(['.clear']); + + const cwd = process.cwd(); + process.chdir(__dirname); + + ['require(\'.', 'require(".'].forEach((input) => { + testMe.complete(input, common.mustCall((err, data) => { + assert.strictEqual(err, null); + assert.strictEqual(data.length, 2); + assert.strictEqual(data[1], '.'); + assert.strictEqual(data[0].length, 2); + assert.ok(data[0].includes('./')); + assert.ok(data[0].includes('../')); + })); + }); + + ['require(\'..', 'require("..'].forEach((input) => { + testMe.complete(input, common.mustCall((err, data) => { + assert.strictEqual(err, null); + assert.deepStrictEqual(data, [['../'], '..']); + })); + }); + + ['./', './test-'].forEach((path) => { + [`require('${path}`, `require("${path}`].forEach((input) => { + testMe.complete(input, common.mustCall((err, data) => { + assert.strictEqual(err, null); + assert.strictEqual(data.length, 2); + assert.strictEqual(data[1], path); + assert.ok(data[0].includes('./test-repl-tab-complete')); + })); + }); + }); + + ['../parallel/', '../parallel/test-'].forEach((path) => { + [`require('${path}`, `require("${path}`].forEach((input) => { + testMe.complete(input, common.mustCall((err, data) => { + assert.strictEqual(err, null); + assert.strictEqual(data.length, 2); + assert.strictEqual(data[1], path); + assert.ok(data[0].includes('../parallel/test-repl-tab-complete')); + })); + }); + }); + + process.chdir(cwd); +} + // Make sure tab completion works on context properties putIn.run(['.clear']);