From 45b730ec42e5dc16ef4c76529a6ec0e979bfc83b Mon Sep 17 00:00:00 2001 From: Alexey Orlenko Date: Fri, 21 Jul 2017 11:30:07 +0300 Subject: [PATCH] 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. PR-URL: https://github.com/nodejs/node/pull/14409 Reviewed-By: Refael Ackermann Reviewed-By: Timothy Gu Reviewed-By: Khaidi Chu Reviewed-By: James M Snell --- lib/repl.js | 13 ++++++- test/parallel/test-repl-tab-complete.js | 50 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) 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']);