diff --git a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java index b450ac26b161..15e34e1e1c74 100644 --- a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java +++ b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java @@ -257,6 +257,7 @@ public class NameUtilTest extends UsefulTestCase { assertMatches("*f", "reformatCode"); assertDoesntMatch("*fc", "reformatCode"); assertDoesntMatch("*sTC", "LazyClassTypeConstructor"); + assertDoesntMatch("*Icon", "LEADING_CONSTRUCTOR"); } public void testMiddleMatchingUnderscore() { diff --git a/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java b/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java index 2ac1ccc79059..4e18662edca8 100644 --- a/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java +++ b/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java @@ -268,7 +268,10 @@ public class MinusculeMatcher implements Matcher { if (!allowSpecialChars && myHasDots && StringUtil.contains(name, nameIndex, nextOccurrence, '.')) { return null; } - if (!isUpperCase[patternIndex] || NameUtil.isWordStart(name, nextOccurrence)) { + // uppercase should match either uppercase or a word start + if (!isUpperCase[patternIndex] || + star && Character.isUpperCase(name.charAt(nextOccurrence)) || + NameUtil.isWordStart(name, nextOccurrence)) { FList ranges = matchFragment(name, patternIndex, nextOccurrence, matchingState); if (ranges != null) { return ranges; @@ -312,8 +315,9 @@ public class MinusculeMatcher implements Matcher { } // middle matches have to be at least of length 2, to prevent too many irrelevant matches - int minFragment = isPatternChar(patternIndex - 1, '*') && Character.isLetterOrDigit(name.charAt(nameIndex)) && !NameUtil - .isWordStart(name, nameIndex) ? 2 : 1; + int minFragment = isPatternChar(patternIndex - 1, '*') && !isWildcard(patternIndex + 1) && + Character.isLetterOrDigit(name.charAt(nameIndex)) && !NameUtil.isWordStart(name, nameIndex) + ? 2 : 1; int i = 1; boolean ignoreCase = myOptions != NameUtil.MatchingCaseSensitivity.ALL; while (nameIndex + i < name.length() && diff --git a/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java b/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java index e068d979f9b4..207f5eb9967a 100644 --- a/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java +++ b/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java @@ -328,10 +328,17 @@ public class NameUtil { static boolean isWordStart(String text, int i) { char c = text.charAt(i); - if (isWordStart(c)) { + if (Character.isUpperCase(c)) { + if (i > 0 && Character.isUpperCase(text.charAt(i - 1))) { + // check that we're not in the middle of an all-caps word + return i + 1 < text.length() && Character.isLowerCase(text.charAt(i + 1)); + } return true; } - if (!Character.isLetterOrDigit(c)) { + if (Character.isDigit(c)) { + return true; + } + if (!Character.isLetter(c)) { return false; } return i == 0 || !Character.isLetterOrDigit(text.charAt(i - 1));