From 880e6dbe092294b62cd584f54024625c852292b4 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 29 May 2013 16:51:26 +0200 Subject: [PATCH] show better matching non-imported classes in autopopup than the imported ones --- .../completion/JavaNoVariantsDelegator.java | 12 ++-- .../completion/impl/BetterPrefixMatcher.java | 59 +++++++++++++++++++ .../impl/RealPrefixMatchingWeigher.java | 5 +- .../src/misc/registry.properties | 1 + .../completion/GroovyNoVariantsDelegator.java | 13 ++-- 5 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/codeInsight/completion/impl/BetterPrefixMatcher.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java index 86162bb89c89..cbfde6328f9c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java @@ -16,6 +16,7 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.ExpectedTypeInfo; +import com.intellij.codeInsight.completion.impl.BetterPrefixMatcher; import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; import com.intellij.codeInsight.lookup.AutoCompletionPolicy; import com.intellij.codeInsight.lookup.LookupElement; @@ -40,9 +41,9 @@ import static com.intellij.patterns.PsiJavaPatterns.psiElement; public class JavaNoVariantsDelegator extends CompletionContributor { @Override - public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) { - final boolean empty = containsOnlyPackages(result.runRemainingContributors(parameters, true)) || - suggestMetaAnnotations(parameters); + public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) { + LinkedHashSet plainResults = result.runRemainingContributors(parameters, true); + final boolean empty = containsOnlyPackages(plainResults) || suggestMetaAnnotations(parameters); if (!empty && parameters.getInvocationCount() == 0) { result.restartCompletionWhenNothingMatches(); @@ -50,10 +51,13 @@ public class JavaNoVariantsDelegator extends CompletionContributor { if (empty) { delegate(parameters, JavaCompletionSorting.addJavaSorting(parameters, result)); - } else if (Registry.is("ide.completion.show.all.classes")) { + } else if (Registry.is("ide.completion.show.all.classes") || Registry.is("ide.completion.show.better.matching.classes")) { if (parameters.getInvocationCount() <= 1 && JavaCompletionContributor.mayStartClassName(result) && JavaCompletionContributor.isClassNamePossible(parameters)) { + if (Registry.is("ide.completion.show.better.matching.classes")) { + result = result.withPrefixMatcher(new BetterPrefixMatcher(result.getPrefixMatcher(), BetterPrefixMatcher.getBestMatchingDegree(plainResults))); + } suggestNonImportedClasses(parameters, result); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/BetterPrefixMatcher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/BetterPrefixMatcher.java new file mode 100644 index 000000000000..968da5f89a31 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/BetterPrefixMatcher.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.completion.impl; + +import com.intellij.codeInsight.completion.CompletionResult; +import com.intellij.codeInsight.completion.PrefixMatcher; +import org.jetbrains.annotations.NotNull; + +import java.util.LinkedHashSet; + +/** + * @author peter + */ +public class BetterPrefixMatcher extends PrefixMatcher { + private final PrefixMatcher myOriginal; + private final int myMinMatchingDegree; + + public BetterPrefixMatcher(PrefixMatcher original, int minMatchingDegree) { + super(original.getPrefix()); + myOriginal = original; + myMinMatchingDegree = minMatchingDegree; + } + + public static int getBestMatchingDegree(LinkedHashSet plainResults) { + int bestMatchingDegree = Integer.MIN_VALUE; + for (CompletionResult cr : plainResults) { + bestMatchingDegree = Math.max(bestMatchingDegree, RealPrefixMatchingWeigher + .getBestMatchingDegree(cr.getLookupElement(), cr.getPrefixMatcher())); + } + return bestMatchingDegree; + } + + @Override + public boolean prefixMatches(@NotNull String name) { + if (!myOriginal.prefixMatches(name) || !myOriginal.isStartMatch(name)) { + return false; + } + return myOriginal.matchingDegree(name) >= myMinMatchingDegree; + } + + @NotNull + @Override + public PrefixMatcher cloneWithPrefix(@NotNull String prefix) { + return new BetterPrefixMatcher(myOriginal.cloneWithPrefix(prefix), myMinMatchingDegree); + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/RealPrefixMatchingWeigher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/RealPrefixMatchingWeigher.java index 26491a0bb36d..9169142f5180 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/RealPrefixMatchingWeigher.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/RealPrefixMatchingWeigher.java @@ -19,13 +19,14 @@ public class RealPrefixMatchingWeigher extends LookupElementWeigher { @Override public Comparable weigh(@NotNull LookupElement element) { - final PrefixMatcher matcher = CompletionServiceImpl.getItemMatcher(element, myLocation.getCompletionParameters().getLookup()); + return getBestMatchingDegree(element, CompletionServiceImpl.getItemMatcher(element, myLocation.getCompletionParameters().getLookup())); + } + public static int getBestMatchingDegree(LookupElement element, PrefixMatcher matcher) { int max = Integer.MIN_VALUE; for (String lookupString : element.getAllLookupStrings()) { max = Math.max(max, matcher.matchingDegree(lookupString)); } return -max; } - } diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 8d7c2f215b1d..224f21b6d8d9 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -215,6 +215,7 @@ documentation.component.editor.font=false find.usage.expand.all=false ide.completion.show.all.classes=false +ide.completion.show.better.matching.classes=false ide.completion.middle.matching=true # suppress inspection "UnusedProperty" diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java index 6862c053d7ef..c00aa41ace6a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java @@ -16,6 +16,7 @@ package org.jetbrains.plugins.groovy.lang.completion; import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.completion.impl.BetterPrefixMatcher; import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; import com.intellij.codeInsight.lookup.AutoCompletionPolicy; import com.intellij.codeInsight.lookup.LookupElement; @@ -48,9 +49,9 @@ public class GroovyNoVariantsDelegator extends CompletionContributor { } @Override - public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) { - final boolean empty = JavaNoVariantsDelegator.containsOnlyPackages(result.runRemainingContributors(parameters, true)) || - suggestMetaAnnotations(parameters); + public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) { + LinkedHashSet plainResults = result.runRemainingContributors(parameters, true); + final boolean empty = JavaNoVariantsDelegator.containsOnlyPackages(plainResults) || suggestMetaAnnotations(parameters); if (!empty && parameters.getInvocationCount() == 0) { result.restartCompletionWhenNothingMatches(); @@ -58,11 +59,15 @@ public class GroovyNoVariantsDelegator extends CompletionContributor { if (empty) { delegate(parameters, result); - } else if (Registry.is("ide.completion.show.all.classes")) { + } else if (Registry.is("ide.completion.show.all.classes") || Registry.is("ide.completion.show.better.matching.classes")) { if (parameters.getInvocationCount() <= 1 && JavaCompletionContributor.mayStartClassName(result) && GroovyCompletionContributor.isClassNamePossible(parameters.getPosition()) && !MapArgumentCompletionProvider.isMapKeyCompletion(parameters)) { + if (Registry.is("ide.completion.show.better.matching.classes")) { + result = result.withPrefixMatcher(new BetterPrefixMatcher(result.getPrefixMatcher(), BetterPrefixMatcher.getBestMatchingDegree(plainResults))); + } + suggestNonImportedClasses(parameters, result); } }