From b646a3df29d85107cd49d5970dcf1cf286d9def8 Mon Sep 17 00:00:00 2001 From: Teddy Katz Date: Wed, 9 Aug 2017 21:51:56 -0700 Subject: [PATCH] repl: include folder extensions in autocomplete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When autocompleting `require` calls, the repl strips .js file extensions from results. However, stripping an extension from a directory results in an error. Update the autocompletion logic to avoid stripping extensions from directories. PR-URL: https://github.com/nodejs/node/pull/14727 Fixes: https://github.com/nodejs/node/issues/14726 Reviewed-By: Rich Trott Reviewed-By: Benjamin Gruenbaum Reviewed-By: Timothy Gu Reviewed-By: Colin Ihrig Reviewed-By: Tobias Nießen Reviewed-By: Yuta Hiroto Reviewed-By: Alexey Orlenko --- lib/repl.js | 35 ++++++++++--------- .../repl-folder-extensions/foo.js/index.js | 0 test/parallel/test-repl-tab-complete.js | 10 ++++++ 3 files changed, 29 insertions(+), 16 deletions(-) create mode 100644 test/fixtures/repl-folder-extensions/foo.js/index.js diff --git a/lib/repl.js b/lib/repl.js index 4a5bc8637b..f745283097 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -822,7 +822,7 @@ function complete(line, callback) { completeOn = match[1]; var subdir = match[2] || ''; filter = match[1]; - var dir, files, f, name, base, ext, abs, subfiles, s; + var dir, files, f, name, base, ext, abs, subfiles, s, isDirectory; group = []; let paths = []; @@ -851,23 +851,26 @@ function complete(line, callback) { // Exclude versioned names that 'npm' installs. continue; } - if (exts.indexOf(ext) !== -1) { - if (!subdir || base !== 'index') { - group.push(subdir + base); - } - } else { - abs = path.resolve(dir, name); + abs = path.resolve(dir, name); + try { + isDirectory = fs.statSync(abs).isDirectory(); + } catch (e) { + continue; + } + if (isDirectory) { + group.push(subdir + name + '/'); try { - if (fs.statSync(abs).isDirectory()) { - group.push(subdir + name + '/'); - subfiles = fs.readdirSync(abs); - for (s = 0; s < subfiles.length; s++) { - if (indexRe.test(subfiles[s])) { - group.push(subdir + name); - } - } + subfiles = fs.readdirSync(abs); + } catch (e) { + continue; + } + for (s = 0; s < subfiles.length; s++) { + if (indexRe.test(subfiles[s])) { + group.push(subdir + name); } - } catch (e) {} + } + } else if (exts.includes(ext) && (!subdir || base !== 'index')) { + group.push(subdir + base); } } } diff --git a/test/fixtures/repl-folder-extensions/foo.js/index.js b/test/fixtures/repl-folder-extensions/foo.js/index.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/parallel/test-repl-tab-complete.js b/test/parallel/test-repl-tab-complete.js index 85bcaf9e61..da8db7a57b 100644 --- a/test/parallel/test-repl-tab-complete.js +++ b/test/parallel/test-repl-tab-complete.js @@ -279,6 +279,16 @@ testMe.complete('require(\'n', common.mustCall(function(error, data) { }); }); + { + const path = '../fixtures/repl-folder-extensions/f'; + testMe.complete(`require('${path}`, common.mustCall((err, data) => { + assert.ifError(err); + assert.strictEqual(data.length, 2); + assert.strictEqual(data[1], path); + assert.ok(data[0].includes('../fixtures/repl-folder-extensions/foo.js')); + })); + } + process.chdir(cwd); }