diff --git a/jdtls.ext/com.microsoft.jdtls.ext.core/plugin.xml b/jdtls.ext/com.microsoft.jdtls.ext.core/plugin.xml index 6c2356c5..dd7b6a5b 100644 --- a/jdtls.ext/com.microsoft.jdtls.ext.core/plugin.xml +++ b/jdtls.ext/com.microsoft.jdtls.ext.core/plugin.xml @@ -4,6 +4,7 @@ + diff --git a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/CommandHandler.java b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/CommandHandler.java index df09f90c..7592ddde 100644 --- a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/CommandHandler.java +++ b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/CommandHandler.java @@ -25,6 +25,8 @@ public Object executeCommand(String commandId, List arguments, IProgress switch (commandId) { case "java.project.list": return ProjectCommand.execute(arguments, monitor); + case "java.project.updateFilters": + return ProjectCommand.updateFilters(arguments, monitor); case "java.getPackageData": return PackageCommand.getChildren(arguments, monitor); case "java.resolvePath": diff --git a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/ProjectCommand.java b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/ProjectCommand.java index ad6c6af3..f40e5c1c 100644 --- a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/ProjectCommand.java +++ b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/ProjectCommand.java @@ -13,10 +13,17 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; +import org.eclipse.core.resources.FileInfoMatcherDescription; import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceFilterDescription; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; @@ -47,6 +54,44 @@ public static List execute(List arguments, IProgressMonitor return children; } + @SuppressWarnings("unchecked") + public static boolean updateFilters(List arguments, IProgressMonitor monitor) throws Exception { + final Set patterns = new HashSet<>((List) arguments.get(0)); + final IProject[] projects = getWorkspaceRoot().getProjects(); + final Set filterUpdated = new HashSet<>(); + for (final IProject project : projects) { + if (!project.exists()) { + continue; + } + final Map filters = Arrays.stream(project.getFilters()).collect(Collectors.toMap( + filter -> (String) filter.getFileInfoMatcherDescription().getArguments(), filter -> filter + )); + for (final String pattern: patterns) { // Handle newly added filters + if (filters.containsKey(pattern)) { + continue; + } + project.createFilter( + IResourceFilterDescription.EXCLUDE_ALL | + IResourceFilterDescription.FILES | + IResourceFilterDescription.FOLDERS | + IResourceFilterDescription.INHERITABLE, + new FileInfoMatcherDescription("org.eclipse.core.resources.regexFilterMatcher", pattern), 0, monitor); + filterUpdated.add(project); + } + for (final String pattern: filters.keySet()) { // Handle deleted filters + if (patterns.contains(pattern)) { + continue; + } + filters.get(pattern).delete(0, monitor); + filterUpdated.add(project); + } + if (filterUpdated.contains(project)) { // Refresh the hierachy if filter is updated + project.refreshLocal(IResource.DEPTH_INFINITE, monitor); + } + } + return filterUpdated.size() > 0; + } + private static IWorkspaceRoot getWorkspaceRoot() { return ResourcesPlugin.getWorkspace().getRoot(); } diff --git a/package-lock.json b/package-lock.json index a81f86e6..d15ea21f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,12 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/braces": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/braces/-/braces-3.0.0.tgz", + "integrity": "sha512-TbH79tcyi9FHwbyboOKeRachRq63mSuWYXOflsNO9ZyE5ClQ/JaozNKl+aWUq87qPNsXasXxi2AbgfwIJ+8GQw==", + "dev": true + }, "@types/events": { "version": "1.2.0", "resolved": "http://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", @@ -42,6 +48,15 @@ "integrity": "sha512-Z6pbDYaWpluqcF8+6qgv6STPEl0jIlyQmpYGwTrzhgwqok8ltBh/p7GAmYnz81wUhxQRhEr8MBpQrB4fQ/hwIA==", "dev": true }, + "@types/micromatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/micromatch/-/micromatch-3.1.1.tgz", + "integrity": "sha512-Wr5y4uv3r7JP4jEUqv7rZeYiMBGRHcbojDVsl11wq6gw1v/ZZQvJexd9rtvVx3EIVqw8dwtcRjSs8m2DV9qHjQ==", + "dev": true, + "requires": { + "@types/braces": "*" + } + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -1087,32 +1102,11 @@ } }, "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "fill-range": "^7.0.1" } }, "brorand": { @@ -2484,24 +2478,19 @@ "dev": true }, "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "to-regex-range": "^5.0.1" }, "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "requires": { - "is-extendable": "^0.1.0" + "is-number": "^7.0.0" } } } @@ -5005,13 +4994,9 @@ "dev": true }, "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "is-plain-object": { "version": "2.0.4", @@ -5829,51 +5814,12 @@ } }, "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } + "braces": "^3.0.1", + "picomatch": "^2.0.5" } }, "miller-rabin": { @@ -6666,6 +6612,11 @@ "sha.js": "^2.4.8" } }, + "picomatch": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.1.tgz", + "integrity": "sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==" + }, "pify": { "version": "2.3.0", "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", @@ -9364,6 +9315,35 @@ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -9403,6 +9383,50 @@ "wrap-ansi": "^5.1.0" } }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -9422,6 +9446,29 @@ "is-glob": "^4.0.0", "micromatch": "^3.0.4", "resolve-dir": "^1.0.1" + }, + "dependencies": { + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } } }, "get-caller-file": { @@ -9468,6 +9515,26 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", diff --git a/package.json b/package.json index 38882567..cb74ea13 100644 --- a/package.json +++ b/package.json @@ -173,6 +173,7 @@ "@types/fs-extra": "^5.0.4", "@types/glob": "^7.1.1", "@types/lodash": "^4.14.139", + "@types/micromatch": "^3.1.1", "@types/mocha": "^5.2.5", "@types/node": "^8.10.36", "@types/vscode": "1.30.0", @@ -195,6 +196,7 @@ "find-java-home": "^0.2.0", "fs-extra": "^7.0.1", "lodash": "^4.17.15", + "micromatch": "^4.0.2", "vscode-extension-telemetry-wrapper": "^0.4.0", "xml2js": "^0.4.19" } diff --git a/src/commands.ts b/src/commands.ts index 430fd354..e2dbebd2 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -28,6 +28,8 @@ export namespace Commands { export const JAVA_PROJECT_LIST = "java.project.list"; + export const JAVA_PROJECT_UPDATE_FILTERS = "java.project.updateFilters"; + export const JAVA_GETPACKAGEDATA = "java.getPackageData"; export const JAVA_RESOLVEPATH = "java.resolvePath"; diff --git a/src/controllers/projectController.ts b/src/controllers/projectController.ts index 2f562b17..df958aa0 100644 --- a/src/controllers/projectController.ts +++ b/src/controllers/projectController.ts @@ -3,15 +3,29 @@ import * as fse from "fs-extra"; import * as _ from "lodash"; +import * as micromatch from "micromatch"; import * as path from "path"; -import { commands, ExtensionContext, Uri, window, workspace } from "vscode"; +import { commands, ConfigurationChangeEvent, Disposable, ExtensionContext, Uri, window, workspace } from "vscode"; +import { instrumentOperation } from "vscode-extension-telemetry-wrapper"; import * as xml2js from "xml2js"; +import { Commands } from "../commands"; +import { Jdtls } from "../java/jdtls"; import { Utility } from "../utility"; -export class ProjectController { - constructor(public readonly context: ExtensionContext) { +export class ProjectController implements Disposable { + public constructor(public readonly context: ExtensionContext) { + context.subscriptions.push(commands.registerCommand(Commands.JAVA_PROJECT_CREATE, + instrumentOperation(Commands.JAVA_PROJECT_CREATE, () => this.createJavaProject()))); + context.subscriptions.push(workspace.onDidChangeConfiguration((e: ConfigurationChangeEvent) => { + if (e.affectsConfiguration("files.exclude")) { + this.refreshExcludeFilters(); + } + })); + this.refreshExcludeFilters(); } + public dispose() {} + public async createJavaProject() { const javaVersion: number = await this.getJavaVersion(); if (!javaVersion) { @@ -96,4 +110,18 @@ export class ProjectController { } return javaVersion; } + + private async refreshExcludeFilters() { + const patterns: string[] = []; + const excludeSetting = workspace.getConfiguration("files", null).get<{ [pattern: string]: boolean }>("exclude"); + for (const pattern of Object.keys(excludeSetting)) { + if (excludeSetting[pattern]) { + patterns.push(micromatch.makeRe(pattern).source); + } + } + const filterUpated = await Jdtls.updateFilters(patterns); + if (filterUpated) { + await commands.executeCommand(Commands.VIEW_PACKAGE_REFRESH, /* debounce = */true); + } + } } diff --git a/src/extension.ts b/src/extension.ts index 8e410178..25e1139e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -20,10 +20,7 @@ function activateExtension(operationId: string, context: ExtensionContext) { Services.initialize(context); Settings.initialize(context); - const projectController: ProjectController = new ProjectController(context); - const instrumented = instrumentOperation(Commands.JAVA_PROJECT_CREATE, () => projectController.createJavaProject()); - context.subscriptions.push(commands.registerCommand(Commands.JAVA_PROJECT_CREATE, instrumented)); - + context.subscriptions.push(new ProjectController(context)); context.subscriptions.push(new DependencyExplorer(context)); } diff --git a/src/java/jdtls.ts b/src/java/jdtls.ts index 8329079d..b5bf267d 100644 --- a/src/java/jdtls.ts +++ b/src/java/jdtls.ts @@ -10,6 +10,10 @@ export namespace Jdtls { return commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.JAVA_PROJECT_LIST, params); } + export function updateFilters(params): Thenable { + return commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.JAVA_PROJECT_UPDATE_FILTERS, params); + } + export function getPackageData(params): Thenable { return commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.JAVA_GETPACKAGEDATA, params); }