From 29a39bc00aca6807bbfe016f1d98b699e5bf68a5 Mon Sep 17 00:00:00 2001 From: Ori Marron Date: Wed, 8 May 2019 11:19:31 +0300 Subject: [PATCH] Add ability to search in parent folders + searchParentModules config field --- extension.js | 31 ++++++++++++++++++++++++------- find-parent-modules.js | 36 ++++++++++++++++++++++++++++++++++++ package.json | 5 +++++ 3 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 find-parent-modules.js diff --git a/extension.js b/extension.js index 035b16e..81478d9 100644 --- a/extension.js +++ b/extension.js @@ -1,6 +1,7 @@ const vscode = require('vscode'); const fs = require('fs'); const path = require('path'); +const { findParentModules } = require('./find-parent-modules'); var lastFolder = ''; var lastWorkspaceName = ''; @@ -16,6 +17,7 @@ exports.activate = context => { const useLastFolder = preferences.get('useLastFolder', false); const nodeModulesPath = preferences.get('path', nodeModules); + const searchParentModules = preferences.get('searchParentModules', true); const searchPath = (workspaceName, workspaceRoot, folderPath) => { // Path to node_modules in this workspace folder @@ -30,7 +32,7 @@ exports.activate = context => { const folderFullPath = path.join(workspaceRoot, folderPath); // Read folder, built quick pick with files/folder (and shortcuts) - fs.readdir(folderFullPath, (readErr, files) => { + fs.readdir(folderFullPath, async (readErr, files) => { if (readErr) { if (folderPath === nodeModulesPath) { return showError('No node_modules folder in this workspace.'); @@ -39,14 +41,29 @@ exports.activate = context => { return showError(`Unable to open folder ${folderPath}`); } - if (folderPath !== nodeModulesPath) { - files.push(''); - files.push(workspaceNodeModules); - files.push('..'); + const isParentFolder = folderPath.includes('..'); + const options = files; + + // If searching in root node_modules, also include modules from parent folders, that are outside of the workspace + if (folderPath === nodeModulesPath) { + if (searchParentModules) { + const parentModules = await findParentModules(workspaceRoot, nodeModulesPath); + options.push(...parentModules); + } + } else { + // Otherwise, show option to move back to root + options.push(''); + options.push(workspaceNodeModules); + + // If current folder is not outside of the workspace, also add option to move a step back + if (!isParentFolder) { + options.push('..'); + } } - vscode.window.showQuickPick(files, { - placeHolder: path.join(workspaceName, folderPath) + + vscode.window.showQuickPick(options, { + placeHolder: path.format({ dir: workspaceName, base: folderPath}) }) .then(selected => { // node_modules shortcut selected diff --git a/find-parent-modules.js b/find-parent-modules.js new file mode 100644 index 0000000..7b56f71 --- /dev/null +++ b/find-parent-modules.js @@ -0,0 +1,36 @@ +const fs = require('fs'); +const path = require('path').posix; +const util = require('util'); + +const fsExists = util.promisify(fs.exists); +const fsReaddir = util.promisify(fs.readdir); + +// Looks for node_modules in parent folders of the workspace recursively. +// Returns a list of paths relative to workspaceRoot/nodeModulesPath +const findParentModules = async (workspaceRoot, nodeModulesPath) => { + const absoluteRootNodeModules = path.join('/', nodeModulesPath); + + const find = async dir => { + const ret = []; + if (await fsExists(dir)) { + const getFilePath = file => + path.relative(path.join(workspaceRoot, nodeModulesPath), path.join(dir, file)); + + const dirFiles = await fsReaddir(dir); + ret.push(...dirFiles.map(getFilePath)); + } + + if (dir !== absoluteRootNodeModules) { + const parent = path.join(dir, '..', '..', nodeModulesPath); + ret.push(...(await find(parent))); + } + + return ret; + }; + + return find(path.join(workspaceRoot, '..', nodeModulesPath)); +}; + +module.exports = { + findParentModules +}; diff --git a/package.json b/package.json index f0e1057..26225bc 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,11 @@ "type": "string", "default": "node_modules", "description": "Relative path to node_modules folder." + }, + "search-node-modules.searchParentModules": { + "type": "boolean", + "default": true, + "description": "Include modules from parent folders in search results." } } }