mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-88058 Completion popup: toggling alpha vs. usage sorting blocks UI
This commit is contained in:
+1
-1
@@ -71,7 +71,7 @@ public abstract class CompletionSortingTestCase extends LightFixtureCompletionTe
|
||||
|
||||
protected static void refreshSorting(final LookupImpl lookup) {
|
||||
lookup.setSelectionTouched(false);
|
||||
lookup.resort();
|
||||
lookup.resort(true);
|
||||
}
|
||||
|
||||
protected static void imitateItemSelection(final LookupImpl lookup, final int index) {
|
||||
|
||||
@@ -15,17 +15,9 @@
|
||||
*/
|
||||
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.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.codeStyle.MinusculeMatcher;
|
||||
import com.intellij.psi.codeStyle.NameUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
@@ -35,43 +27,4 @@ public class PrefixMatchingWeigher extends CompletionWeigher {
|
||||
public Comparable weigh(@NotNull LookupElement element, @NotNull CompletionLocation location) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
public static int getPrefixMatchingDegree(LookupElement item, CompletionLocation location) {
|
||||
final MinusculeMatcher matcher = getMinusculeMatcher(location.getCompletionParameters().getLookup().itemPattern(item));
|
||||
|
||||
int max = Integer.MIN_VALUE;
|
||||
for (String lookupString : item.getAllLookupStrings()) {
|
||||
max = Math.max(max, matcher.matchingDegree(lookupString));
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
private static MinusculeMatcher getMinusculeMatcher(String prefix) {
|
||||
final int setting = CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE;
|
||||
final NameUtil.MatchingCaseSensitivity sensitivity =
|
||||
setting == CodeInsightSettings.NONE ? NameUtil.MatchingCaseSensitivity.NONE :
|
||||
setting == CodeInsightSettings.FIRST_LETTER ? NameUtil.MatchingCaseSensitivity.FIRST_LETTER : NameUtil.MatchingCaseSensitivity.ALL;
|
||||
return new MinusculeMatcher(CamelHumpMatcher.applyMiddleMatching(prefix), sensitivity);
|
||||
}
|
||||
|
||||
public static boolean isMiddleMatch(LookupElement element, CompletionLocation location) {
|
||||
String prefix = location.getCompletionParameters().getLookup().itemPattern(element);
|
||||
if (StringUtil.isNotEmpty(prefix)) {
|
||||
MinusculeMatcher matcher = getMinusculeMatcher(prefix);
|
||||
for (String ls : element.getAllLookupStrings()) {
|
||||
Iterable<TextRange> fragments = matcher.matchingFragments(ls);
|
||||
if (fragments != null) {
|
||||
Iterator<TextRange> iterator = fragments.iterator();
|
||||
if (!ls.isEmpty() && prefix.charAt(0) == ls.charAt(0)) {
|
||||
return false;
|
||||
}
|
||||
if (iterator.hasNext() && iterator.next().contains(0)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+58
-2
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.completion.impl;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.codeInsight.completion.*;
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -25,11 +26,16 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.project.ProjectManagerAdapter;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.Weigher;
|
||||
import com.intellij.psi.WeighingService;
|
||||
import com.intellij.psi.codeStyle.MinusculeMatcher;
|
||||
import com.intellij.psi.codeStyle.NameUtil;
|
||||
import com.intellij.psi.impl.DebugUtil;
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
@@ -37,6 +43,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -45,6 +52,7 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.impl.CompletionServiceImpl");
|
||||
private static volatile CompletionPhase ourPhase = CompletionPhase.NoCompletion;
|
||||
private static String ourPhaseTrace;
|
||||
private static CodeInsightSettings ourSettings = CodeInsightSettings.getInstance();
|
||||
|
||||
public CompletionServiceImpl() {
|
||||
ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerAdapter() {
|
||||
@@ -103,6 +111,54 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int getPrefixMatchingDegree(LookupElement item, CompletionLocation location) {
|
||||
final MinusculeMatcher matcher = getMinusculeMatcher(location.getCompletionParameters().getLookup().itemPattern(item));
|
||||
|
||||
int max = Integer.MIN_VALUE;
|
||||
for (String lookupString : item.getAllLookupStrings()) {
|
||||
max = Math.max(max, matcher.matchingDegree(lookupString));
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
private static volatile Pair<String, MinusculeMatcher> lastMatcher;
|
||||
|
||||
private static MinusculeMatcher getMinusculeMatcher(String prefix) {
|
||||
final int setting = ourSettings.COMPLETION_CASE_SENSITIVE;
|
||||
final NameUtil.MatchingCaseSensitivity sensitivity =
|
||||
setting == CodeInsightSettings.NONE ? NameUtil.MatchingCaseSensitivity.NONE :
|
||||
setting == CodeInsightSettings.FIRST_LETTER ? NameUtil.MatchingCaseSensitivity.FIRST_LETTER : NameUtil.MatchingCaseSensitivity.ALL;
|
||||
|
||||
Pair<String, MinusculeMatcher> pair = lastMatcher;
|
||||
if (pair != null && pair.first.equals(prefix)) {
|
||||
return pair.second;
|
||||
}
|
||||
|
||||
MinusculeMatcher matcher = new MinusculeMatcher(CamelHumpMatcher.applyMiddleMatching(prefix), sensitivity);
|
||||
lastMatcher = Pair.create(prefix, matcher);
|
||||
return matcher;
|
||||
}
|
||||
|
||||
private static boolean isMiddleMatch(LookupElement element, CompletionLocation location) {
|
||||
String prefix = location.getCompletionParameters().getLookup().itemPattern(element);
|
||||
if (StringUtil.isNotEmpty(prefix)) {
|
||||
MinusculeMatcher matcher = getMinusculeMatcher(prefix);
|
||||
for (String ls : element.getAllLookupStrings()) {
|
||||
Iterable<TextRange> fragments = matcher.matchingFragments(ls);
|
||||
if (fragments != null) {
|
||||
Iterator<TextRange> iterator = fragments.iterator();
|
||||
if (!ls.isEmpty() && prefix.charAt(0) == ls.charAt(0)) {
|
||||
return false;
|
||||
}
|
||||
if (iterator.hasNext() && iterator.next().contains(0)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class CompletionResultSetImpl extends CompletionResultSet {
|
||||
private final String myTextBeforePosition;
|
||||
private final CompletionParameters myParameters;
|
||||
@@ -244,7 +300,7 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable getWeight(LookupElement element) {
|
||||
return PrefixMatchingWeigher.isMiddleMatch(element, location);
|
||||
return isMiddleMatch(element, location);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -260,7 +316,7 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable getWeight(LookupElement element) {
|
||||
return -PrefixMatchingWeigher.getPrefixMatchingDegree(element, location);
|
||||
return -getPrefixMatchingDegree(element, location);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -36,11 +36,6 @@ public abstract class LookupArranger {
|
||||
|
||||
public abstract Pair<List<LookupElement>, Integer> arrangeItems(@NotNull Lookup lookup, boolean onExplicitAction);
|
||||
|
||||
public final void clearItems() {
|
||||
prefixChanged();
|
||||
myItems.clear();
|
||||
}
|
||||
|
||||
public abstract LookupArranger createEmptyCopy();
|
||||
|
||||
protected static void addPrefixItems(Lookup lookup, LinkedHashSet<LookupElement> result, boolean exactly, Collection<LookupElement> items) {
|
||||
|
||||
@@ -260,7 +260,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
mySortingLabel.setIcon(lexi ? lexiSortIcon : relevanceSortIcon);
|
||||
mySortingLabel.setToolTipText(lexi ? "Click to sort variants by relevance" : "Click to sort variants alphabetically");
|
||||
|
||||
resort();
|
||||
resort(false);
|
||||
}
|
||||
|
||||
public void setArranger(LookupArranger arranger) {
|
||||
@@ -314,7 +314,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
mySelectionTouched = selectionTouched;
|
||||
}
|
||||
|
||||
public void resort() {
|
||||
public void resort(boolean addAgain) {
|
||||
final List<LookupElement> items = getItems();
|
||||
|
||||
synchronized (myList) {
|
||||
@@ -322,8 +322,10 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
((DefaultListModel)myList.getModel()).clear();
|
||||
}
|
||||
|
||||
for (final LookupElement item : items) {
|
||||
addItem(item, itemMatcher(item));
|
||||
if (addAgain) {
|
||||
for (final LookupElement item : items) {
|
||||
addItem(item, itemMatcher(item));
|
||||
}
|
||||
}
|
||||
refreshUi(true, true);
|
||||
}
|
||||
@@ -529,7 +531,8 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
@NotNull
|
||||
@Override
|
||||
public String itemPattern(@NotNull LookupElement element) {
|
||||
return itemMatcher(element).getPrefix() + myAdditionalPrefix;
|
||||
String prefix = itemMatcher(element).getPrefix();
|
||||
return myAdditionalPrefix.isEmpty() ? prefix : prefix + myAdditionalPrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user