IDEA-84485 Allow auto-completion by typing the middle of a word (hidden for now)

This commit is contained in:
peter
2012-04-20 20:47:09 +02:00
parent 86b315e0c5
commit e34e2f5a98
6 changed files with 37 additions and 14 deletions
@@ -942,8 +942,8 @@ public class ListUtils {
assertNotNull(getLookup());
type('*fz');
final List<LookupElement> list = getLookup().getItems();
assertEquals("azzzfzzz", list.get(0).getLookupString());
assertEquals("fzazzz", list.get(1).getLookupString());
assertEquals("azzzfzzz", list.get(1).getLookupString());
assertEquals("fzazzz", list.get(0).getLookupString());
}
public void testTabReplacesMethodNameWithLocalVariableName() throws Throwable { doTest('\t'); }
@@ -16,6 +16,7 @@
package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.psi.codeStyle.NameUtil;
import org.jetbrains.annotations.NotNull;
@@ -37,7 +38,7 @@ public class PrefixMatchingWeigher extends CompletionWeigher {
final NameUtil.MatchingCaseSensitivity sensitivity =
setting == CodeInsightSettings.NONE ? NameUtil.MatchingCaseSensitivity.NONE :
setting == CodeInsightSettings.FIRST_LETTER ? NameUtil.MatchingCaseSensitivity.FIRST_LETTER : NameUtil.MatchingCaseSensitivity.ALL;
final NameUtil.MinusculeMatcher matcher = new NameUtil.MinusculeMatcher(prefix, sensitivity);
final NameUtil.MinusculeMatcher matcher = new NameUtil.MinusculeMatcher(CamelHumpMatcher.applyMiddleMatching(prefix), sensitivity);
int max = Integer.MIN_VALUE;
for (String lookupString : item.getAllLookupStrings()) {
@@ -4,6 +4,8 @@ package com.intellij.codeInsight.completion.impl;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.completion.PrefixMatcher;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.util.containers.hash.LinkedHashMap;
@@ -64,7 +66,7 @@ public class CamelHumpMatcher extends PrefixMatcher {
String key = relax + myPrefix + caseSensitive;
Matcher pattern = ourPatternCache.get(key);
if (pattern == null) {
pattern = createCamelHumpsMatcher(relax, caseSensitive);
pattern = createCamelHumpsMatcher(relax, caseSensitive, myPrefix);
ourPatternCache.put(key, pattern);
}
return pattern;
@@ -102,28 +104,37 @@ public class CamelHumpMatcher extends PrefixMatcher {
return new CamelHumpMatcher(prefix, myCaseSensitive, myRelaxedMatching);
}
private Matcher createCamelHumpsMatcher(final boolean relaxedMatching, final boolean caseSensitive) {
private static Matcher createCamelHumpsMatcher(final boolean relaxedMatching, final boolean caseSensitive, String prefix) {
prefix = applyMiddleMatching(prefix);
if (!caseSensitive) {
return NameUtil.buildCompletionMatcher(myPrefix, 0, true, true);
return NameUtil.buildCompletionMatcher(prefix, 0, true, true);
}
if (relaxedMatching) {
return NameUtil.buildCompletionMatcher(myPrefix, 0, true, true);
return NameUtil.buildCompletionMatcher(prefix, 0, true, true);
}
switch (CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE) {
case CodeInsightSettings.NONE:
return NameUtil.buildCompletionMatcher(myPrefix, 0, true, true);
return NameUtil.buildCompletionMatcher(prefix, 0, true, true);
case CodeInsightSettings.FIRST_LETTER:
int exactPrefixLen = myPrefix.startsWith("*") ? 0 : 1;
return NameUtil.buildCompletionMatcher(myPrefix, exactPrefixLen, true, true);
int exactPrefixLen = prefix.startsWith("*") ? 0 : 1;
return NameUtil.buildCompletionMatcher(prefix, exactPrefixLen, true, true);
case CodeInsightSettings.ALL:
return NameUtil.buildCompletionMatcher(myPrefix, 1, false, false);
return NameUtil.buildCompletionMatcher(prefix, 1, false, false);
default:
return NameUtil.buildCompletionMatcher(myPrefix, 0, true, false);
return NameUtil.buildCompletionMatcher(prefix, 0, true, false);
}
}
public static String applyMiddleMatching(String prefix) {
if (Registry.is("ide.completion.middle.matching") && !ApplicationManager.getApplication().isUnitTestMode()) {
return " " + prefix;
}
return prefix;
}
@Override
public String toString() {
return myPrefix;
@@ -181,6 +181,9 @@ projectView.hide.dot.idea=true
show.live.templates.in.completion=false
documentation.component.editor.font=false
ide.completion.middle.matching=false
ide.completion.middle.matching.description=Suggest items in completion that contain the entered string somewhere in the middle
show.all.classes.on.first.completion=false
ide.enable.toolwindow.stack=false
@@ -119,6 +119,8 @@ public class NameUtilTest extends UsefulTestCase {
assertMatches("foo bar", "fooGooBar");
assertMatches("foo bar", "fooGoo bar");
assertDoesntMatch(" b", "fbi");
assertTrue(NameUtil.buildCompletionMatcher(" us", 0, true, true).matches("getUsage"));
assertTrue(NameUtil.buildCompletionMatcher(" us", 0, true, true).matches("getMyUsage"));
}
public void testIDEADEV15503() throws Exception {
@@ -211,6 +213,8 @@ public class NameUtilTest extends UsefulTestCase {
assertMatches("*Git*", "AtpGenerationItem");
assertMatches("Collec*Util*", "CollectionUtils");
assertMatches("Collec*Util*", "CollectionUtilsTest");
assertTrue(NameUtil.buildCompletionMatcher("*us", 0, true, true).matches("usage"));
assertTrue(NameUtil.buildCompletionMatcher(" us", 0, true, true).matches("usage"));
}
public void testSpaceInCompletionPrefix() throws Exception {
@@ -358,6 +362,7 @@ public class NameUtilTest extends UsefulTestCase {
assertPreference("*f", "barfoo", "barFoo");
assertPreference("*f", "barfoo", "foo");
assertPreference("*f", "asdf", "Foo", NameUtil.MatchingCaseSensitivity.NONE);
assertPreference(" sto", "ArrayStoreException", "StackOverflowError", NameUtil.MatchingCaseSensitivity.NONE);
}
private static void assertPreference(@NonNls String pattern,
@@ -335,6 +335,9 @@ public class NameUtil {
if (isWordStart(text.charAt(i))) {
return true;
}
if (!Character.isLetterOrDigit(text.charAt(i))) {
return false;
}
if (i > 0 && MinusculeMatcher.isWordSeparator(text.charAt(i - 1))) {
return true;
}
@@ -600,7 +603,7 @@ public class NameUtil {
}
}
if (isWordStart(name, nameIndex)) {
if (nameIndex == 0 || isWordStart(name, nameIndex)) {
FList<TextRange> ranges = matchName(name, patternIndex, nameIndex);
if (ranges != null) {
return ranges;
@@ -657,7 +660,7 @@ public class NameUtil {
boolean prefixMatching = first != null && first.getStartOffset() == 0;
boolean middleWordStart = first != null && first.getStartOffset() > 0 && isWordStart(name, first.getStartOffset());
return -fragmentCount + matchingCaps * 10 + commonStart * 2 + (prefixMatching ? 2 : middleWordStart ? 1 : 0);
return -fragmentCount + matchingCaps * 10 + commonStart + (prefixMatching ? 2 : middleWordStart ? 1 : 0) * 100;
}
@Override