diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/LayoutProjectCodeDialog.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/LayoutProjectCodeDialog.java index 1b389eaad088..97f1c50865f6 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/LayoutProjectCodeDialog.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/LayoutProjectCodeDialog.java @@ -35,7 +35,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.awt.event.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; import java.util.regex.PatternSyntaxException; /** @@ -163,7 +166,7 @@ public class LayoutProjectCodeDialog extends DialogWrapper implements ReformatFi private static boolean isMaskValid(@NotNull String mask) { try { - FindInProjectUtil.createFileMaskRegExp(mask); + FindInProjectUtil.createFileMaskCondition(mask); } catch (PatternSyntaxException e) { return false; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java index 8441bfc075c5..3303609ed529 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java @@ -29,6 +29,8 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Conditions; import com.intellij.openapi.vfs.ReadonlyStatusHandler; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileFilter; @@ -43,7 +45,6 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import java.util.ArrayList; -import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; public class ReformatCodeAction extends AnAction implements DumbAware { @@ -242,24 +243,21 @@ public class ReformatCodeAction extends AnAction implements DumbAware { if (fileTypeMask == null) return; - final Pattern pattern = getFileTypeMaskPattern(fileTypeMask); - if (pattern != null) { - processor.addFileFilter(new VirtualFileFilter() { + final Condition patternCondition = getFileTypeMaskPattern(fileTypeMask); + processor.addFileFilter(new VirtualFileFilter() { @Override public boolean accept(@NotNull VirtualFile file) { - return pattern.matcher(file.getName()).matches(); + return patternCondition.value(file.getName()); } }); - } } - @Nullable - private static Pattern getFileTypeMaskPattern(@Nullable String mask) { + private static Condition getFileTypeMaskPattern(@Nullable String mask) { try { - return FindInProjectUtil.createFileMaskRegExp(mask); + return FindInProjectUtil.createFileMaskCondition(mask); } catch (PatternSyntaxException e) { LOG.info("Error while processing file mask: ", e); - return null; + return Conditions.alwaysTrue(); } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/actions/FileFilterPanel.java b/platform/lang-impl/src/com/intellij/codeInspection/actions/FileFilterPanel.java index 47ab269f6836..af580cd1236e 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/actions/FileFilterPanel.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/actions/FileFilterPanel.java @@ -18,13 +18,13 @@ package com.intellij.codeInspection.actions; import com.intellij.find.impl.FindDialog; import com.intellij.find.impl.FindInProjectUtil; import com.intellij.openapi.module.Module; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.regex.Pattern; /** * @author Dmitry Avdeev @@ -45,11 +45,11 @@ class FileFilterPanel { String text = (String)myFileMask.getSelectedItem(); if (text == null) return null; - final Pattern pattern = FindInProjectUtil.createFileMaskRegExp(text); + final Condition patternCondition = FindInProjectUtil.createFileMaskCondition(text); return new GlobalSearchScope() { @Override public boolean contains(@NotNull VirtualFile file) { - return pattern == null || pattern.matcher(file.getName()).matches(); + return patternCondition.value(file.getName()); } @Override diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java index dfb0d85993c7..e33e7d3b2887 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java @@ -905,7 +905,7 @@ public class FindDialog extends DialogWrapper { else { try { - FindInProjectUtil.createFileMaskRegExp(mask); // verify that the regexp compiles + FindInProjectUtil.createFileMaskCondition(mask); // verify that the regexp compiles } catch (PatternSyntaxException ex) { return new ValidationInfo(FindBundle.message("find.filter.invalid.file.mask.error", mask), myFileFilter); @@ -1510,7 +1510,7 @@ public class FindDialog extends DialogWrapper { private String getFileTypeMask() { String mask = null; if (myUseFileFilter !=null && myUseFileFilter.isSelected()) { - mask = (String)myFileFilter.getSelectedItem(); + mask = (String)myFileFilter.getEditor().getItem(); } return mask; } diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java index deb4e5db3065..9f9daaf13d56 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java @@ -38,7 +38,6 @@ import com.intellij.openapi.project.ProjectCoreUtil; import com.intellij.openapi.roots.*; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Condition; -import com.intellij.openapi.util.Conditions; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.TrigramBuilder; @@ -68,7 +67,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; -import java.util.regex.Pattern; /** * @author peter @@ -107,13 +105,12 @@ class FindInProjectTask { myProjectFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); myFileIndex = myModule == null ? myProjectFileIndex : ModuleRootManager.getInstance(myModule).getFileIndex(); - final String filter = findModel.getFileFilter(); - final Pattern pattern = FindInProjectUtil.createFileMaskRegExp(filter); + final Condition patternCondition = FindInProjectUtil.createFileMaskCondition(findModel.getFileFilter()); - myFileMask = pattern == null ? Conditions.alwaysTrue() : new Condition() { + myFileMask = new Condition() { @Override public boolean value(VirtualFile file) { - return file != null && pattern.matcher(file.getName()).matches(); + return file != null && patternCondition.value(file.getName()); } }; @@ -450,7 +447,11 @@ class FindInProjectTask { final GlobalSearchScope scope = toGlobal(FindInProjectUtil.getScopeFromModel(myProject, myFindModel)); final Set resultFiles = new LinkedHashSet(); - resultFiles.addAll(myFilesToScanInitially); + for(VirtualFile file:myFilesToScanInitially) { + if (myFileMask.value(file)) { + resultFiles.add(file); + } + } if (TrigramIndex.ENABLED) { final Set keys = ContainerUtil.newTroveSet(); diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java index b1a5c12d9123..706984453df4 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java @@ -41,9 +41,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.ProjectFileIndex; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.Factory; -import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.ex.VirtualFileManagerEx; @@ -66,6 +64,7 @@ import javax.swing.*; import java.io.File; import java.util.*; import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; public class FindInProjectUtil { private static final int USAGES_PER_READ_ACTION = 100; @@ -153,7 +152,42 @@ public class FindInProjectUtil { } + /* filter can have form "*.js, !*_min.js", latter means except matched by *_min.js */ + @NotNull + public static Condition createFileMaskCondition(@Nullable String filter) throws PatternSyntaxException { + if (filter == null) { + return Conditions.alwaysTrue(); + } + String pattern = ""; + String negativePattern = ""; + final List masks = StringUtil.split(filter, ","); + + for(String mask:masks) { + mask = mask.trim(); + if (StringUtil.startsWith(mask, "!")) { + negativePattern += "(" + PatternUtil.convertToRegex(mask.substring(1)) + ")"; + } else { + pattern += "(" + PatternUtil.convertToRegex(mask) + ")"; + } + } + + final String finalPattern = pattern; + final String finalNegativePattern = negativePattern; + + return new Condition() { + final Pattern regExp = Pattern.compile(finalPattern, Pattern.CASE_INSENSITIVE); + final Pattern negativeRegExp = StringUtil.isEmpty(finalNegativePattern) ? null : Pattern.compile(finalNegativePattern, Pattern.CASE_INSENSITIVE); + @Override + public boolean value(String input) { + return regExp.matcher(input).matches() && (negativeRegExp == null || !negativeRegExp.matcher(input).matches()); + } + }; + } + + /** + * @deprecated to be removed in IDEA 16 + */ @Nullable public static Pattern createFileMaskRegExp(@Nullable String filter) { if (filter == null) {