diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/PreferenceManager.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/PreferenceManager.java index 722101da5c..e96f2c1f8f 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/PreferenceManager.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/PreferenceManager.java @@ -227,6 +227,9 @@ public void update(Preferences preferences) { Hashtable options = JavaCore.getOptions(); preferences.updateTabSizeInsertSpaces(options); JavaCore.setOptions(options); + List resourceFilters = preferences.getResourceFilters(); + IEclipsePreferences eclipsePreferences = InstanceScope.INSTANCE.getNode(IConstants.PLUGIN_ID); + eclipsePreferences.put(Preferences.JAVA_RESOURCE_FILTERS, String.join("::", resourceFilters)); // TODO serialize preferences } diff --git a/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JDTLSFilesystemActivator.java b/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JDTLSFilesystemActivator.java index 6b930e88fc..39993310b4 100644 --- a/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JDTLSFilesystemActivator.java +++ b/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JDTLSFilesystemActivator.java @@ -1,5 +1,14 @@ package org.eclipse.jdt.ls.core.internal.filesystem; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.regex.Pattern; + +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; +import org.eclipse.core.runtime.preferences.InstanceScope; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; @@ -15,6 +24,12 @@ public class JDTLSFilesystemActivator implements BundleActivator { private static BundleContext context; + private static final String JAVA_LS_PLUGIN_ID = "org.eclipse.jdt.ls.core"; + private static final String JAVA_RESOURCE_FILTERS = "java.project.resourceFilters"; + private static final String JAVA_RESOURCE_FILTERS_DEFAULT = "node_modules::\\.git"; + private List resuorcePatterns; + private String resourceFilters; + private static JDTLSFilesystemActivator instance; static BundleContext getContext() { return context; @@ -22,10 +37,47 @@ static BundleContext getContext() { public void start(BundleContext bundleContext) throws Exception { JDTLSFilesystemActivator.context = bundleContext; + this.instance = this; + configureResourceFilters(); + } + + private void configureResourceFilters() { + IEclipsePreferences eclipsePreferences = InstanceScope.INSTANCE.getNode(JAVA_LS_PLUGIN_ID); + if (eclipsePreferences != null) { + resourceFilters = eclipsePreferences.get(JAVA_RESOURCE_FILTERS, JAVA_RESOURCE_FILTERS_DEFAULT); + eclipsePreferences.addPreferenceChangeListener(new IPreferenceChangeListener() { + + @Override + public void preferenceChange(PreferenceChangeEvent event) { + if (event.getNewValue() instanceof String newValue && Objects.equals(JAVA_RESOURCE_FILTERS, event.getKey()) && !Objects.equals(resourceFilters, event.getNewValue())) { + resourceFilters = newValue; + setResourcePatterns(); + } + } + }); + } else { + resourceFilters = JAVA_RESOURCE_FILTERS_DEFAULT; + } + setResourcePatterns(); + } + + protected void setResourcePatterns() { + resuorcePatterns = new ArrayList<>(); + for (String element: resourceFilters.split("::")) { + Pattern pattern = Pattern.compile(element); + resuorcePatterns.add(pattern); + } } public void stop(BundleContext bundleContext) throws Exception { JDTLSFilesystemActivator.context = null; } + public static List getResuorcePatterns() { + if (instance != null) { + return instance.resuorcePatterns; + } + return null; + } + } diff --git a/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFile.java b/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFile.java index f5770486f3..a07f5c8e53 100644 --- a/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFile.java +++ b/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFile.java @@ -20,6 +20,7 @@ import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.internal.filesystem.local.LocalFile; +import org.eclipse.core.internal.preferences.EclipsePreferences; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; @@ -50,6 +51,9 @@ public String[] childNames(int options, IProgressMonitor monitor) { } IPath filePath = new Path(this.filePath); + if (JLSFsUtils.isExcluded(filePath)) { + return childNames; + } String projectName = JLSFsUtils.getProjectNameIfLocationIsProjectRoot(filePath); if (projectName == null) { return childNames; @@ -69,7 +73,7 @@ public String[] childNames(int options, IProgressMonitor monitor) { @Override public IFileStore getChild(String name) { IPath path = new Path(this.filePath).append(name); - if (JLSFsUtils.shouldStoreInMetadataArea(path)) { + if (JLSFsUtils.shouldStoreInMetadataArea(path) && !JLSFsUtils.isExcluded(path)) { IPath containerPath = JLSFsUtils.getContainerPath(path); String projectName = JLSFsUtils.getProjectNameIfLocationIsProjectRoot(containerPath); if (projectName == null) { @@ -87,7 +91,7 @@ public IFileStore getChild(String name) { @Override public IFileStore getFileStore(IPath path) { IPath fullPath = new Path(this.filePath).append(path); - if (JLSFsUtils.shouldStoreInMetadataArea(fullPath)) { + if (JLSFsUtils.shouldStoreInMetadataArea(fullPath) && !JLSFsUtils.isExcluded(fullPath)) { IPath containerPath = JLSFsUtils.getContainerPath(fullPath); String projectName = JLSFsUtils.getProjectNameIfLocationIsProjectRoot(containerPath); if (projectName == null) { diff --git a/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFsUtils.java b/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFsUtils.java index b898ccda93..ee79837f98 100644 --- a/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFsUtils.java +++ b/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFsUtils.java @@ -17,6 +17,8 @@ import java.util.HashSet; import java.util.Objects; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.eclipse.core.internal.preferences.EclipsePreferences; import org.eclipse.core.resources.IContainer; @@ -24,6 +26,8 @@ import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jdt.core.IJavaProject; /** @@ -110,6 +114,27 @@ static boolean isProjectMetadataFile(IPath location) { return true; } + /** + * Check whether the given location is excluded + * @param location file location. + * @return whether the given location is excluded. + */ + public static boolean isExcluded(IPath path) { + if (path != null && JDTLSFilesystemActivator.getResuorcePatterns() != null) { + for (String segment: path.segments()) { + for (Pattern pattern: JDTLSFilesystemActivator.getResuorcePatterns()) { + Matcher m = pattern.matcher(segment); + if (m.matches()) { + return true; + } + } + } + return false; + } else { + return true; + } + } + /** * Get the container path of the given file path. * If the file path is a preferences file, the grand-parent container will be returned. diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFsUtilsTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFsUtilsTest.java index 51699f796a..71836ed688 100644 --- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFsUtilsTest.java +++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFsUtilsTest.java @@ -16,6 +16,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; import org.junit.Test; public class JLSFsUtilsTest { @@ -35,4 +37,10 @@ public void testNotGeneratesMetadataFilesAtProjectRoot() { public void testGeneratesMetadataFilesAtProjectRootWhenNotSet() { assertTrue(JLSFsUtils.generatesMetadataFilesAtProjectRoot()); } + + @Test + public void testExcluded() { + IPath path = new Path("/project/node_modules"); + assertTrue(JLSFsUtils.isExcluded(path)); + } }