mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
suggest start match classes first
This commit is contained in:
@@ -139,34 +139,39 @@ public class AllClassesGetter {
|
||||
}
|
||||
};
|
||||
|
||||
public static void processJavaClasses(CompletionParameters parameters,
|
||||
public static void processJavaClasses(final CompletionParameters parameters,
|
||||
final PrefixMatcher prefixMatcher, final boolean filterByScope,
|
||||
final Consumer<PsiClass> consumer) {
|
||||
final PsiElement context = parameters.getPosition();
|
||||
final String packagePrefix = getPackagePrefix(context, parameters.getOffset());
|
||||
|
||||
final Set<String> qnames = new THashSet<String>();
|
||||
|
||||
final Project project = context.getProject();
|
||||
final GlobalSearchScope scope = filterByScope ? context.getContainingFile().getResolveScope() : GlobalSearchScope.allScope(project);
|
||||
final boolean pkgContext = JavaCompletionUtil.inSomePackage(context);
|
||||
|
||||
AllClassesSearch.search(scope, project, new Condition<String>() {
|
||||
public boolean value(String s) {
|
||||
return prefixMatcher.prefixMatches(s);
|
||||
}
|
||||
}).forEach(new Processor<PsiClass>() {
|
||||
Processor<PsiClass> processor = new Processor<PsiClass>() {
|
||||
final Set<String> qNames = new THashSet<String>();
|
||||
final boolean pkgContext = JavaCompletionUtil.inSomePackage(context);
|
||||
final String packagePrefix = getPackagePrefix(context, parameters.getOffset());
|
||||
|
||||
public boolean process(PsiClass psiClass) {
|
||||
assert psiClass != null;
|
||||
if (isAcceptableInContext(context, psiClass, filterByScope, pkgContext)) {
|
||||
String qName = psiClass.getQualifiedName();
|
||||
if (qName != null && qName.startsWith(packagePrefix) && qnames.add(qName)) {
|
||||
if (qName != null && qName.startsWith(packagePrefix) && qNames.add(qName)) {
|
||||
consumer.consume(psiClass);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
};
|
||||
AllClassesSearch.search(scope, project, new Condition<String>() {
|
||||
public boolean value(String s) {
|
||||
return prefixMatcher.isStartMatch(s);
|
||||
}
|
||||
}).forEach(processor);
|
||||
AllClassesSearch.search(scope, project, new Condition<String>() {
|
||||
public boolean value(String s) {
|
||||
return prefixMatcher.prefixMatches(s);
|
||||
}
|
||||
}).forEach(processor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -11,11 +12,14 @@ public class PlainPrefixMatcher extends PrefixMatcher {
|
||||
super(prefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStartMatch(String name) {
|
||||
return StringUtil.startsWithIgnoreCase(name, getPrefix());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean prefixMatches(@NotNull String name) {
|
||||
final String lowerPrefix = getPrefix().toLowerCase();
|
||||
final String lowerName = name.toLowerCase();
|
||||
return lowerName.contains(lowerPrefix);
|
||||
return StringUtil.containsIgnoreCase(name, getPrefix());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -23,6 +23,10 @@ public abstract class PrefixMatcher {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isStartMatch(String name) {
|
||||
return prefixMatches(name);
|
||||
}
|
||||
|
||||
public abstract boolean prefixMatches(@NotNull String name);
|
||||
|
||||
@NotNull
|
||||
|
||||
+8
-3
@@ -7,15 +7,15 @@ 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.MinusculeMatcher;
|
||||
import com.intellij.psi.codeStyle.NameUtil;
|
||||
import com.intellij.util.text.Matcher;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class CamelHumpMatcher extends PrefixMatcher {
|
||||
private final Matcher myMatcher;
|
||||
private final MinusculeMatcher myMatcher;
|
||||
private final boolean myCaseSensitive;
|
||||
|
||||
public CamelHumpMatcher(@NotNull final String prefix) {
|
||||
@@ -28,6 +28,11 @@ public class CamelHumpMatcher extends PrefixMatcher {
|
||||
myMatcher = createMatcher(myCaseSensitive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStartMatch(String name) {
|
||||
return myMatcher.isStartMatch(name);
|
||||
}
|
||||
|
||||
public boolean prefixMatches(@NotNull final String name) {
|
||||
return myMatcher.matches(name);
|
||||
}
|
||||
@@ -55,7 +60,7 @@ public class CamelHumpMatcher extends PrefixMatcher {
|
||||
return new CamelHumpMatcher(prefix, myCaseSensitive);
|
||||
}
|
||||
|
||||
private Matcher createMatcher(final boolean caseSensitive) {
|
||||
private MinusculeMatcher createMatcher(final boolean caseSensitive) {
|
||||
String prefix = applyMiddleMatching(myPrefix);
|
||||
|
||||
if (!caseSensitive) {
|
||||
|
||||
+53
-46
@@ -27,8 +27,6 @@ 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;
|
||||
@@ -43,7 +41,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -62,7 +59,8 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
if (indicator != null && indicator.getProject() == project) {
|
||||
LookupManager.getInstance(indicator.getProject()).hideActiveLookup();
|
||||
setCompletionPhase(CompletionPhase.NoCompletion);
|
||||
} else if (indicator == null) {
|
||||
}
|
||||
else if (indicator == null) {
|
||||
setCompletionPhase(CompletionPhase.NoCompletion);
|
||||
}
|
||||
}
|
||||
@@ -139,23 +137,6 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
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 (!iterator.hasNext() || MinusculeMatcher.isStartMatch(ls, iterator.next().getStartOffset())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class CompletionResultSetImpl extends CompletionResultSet {
|
||||
private final String myTextBeforePosition;
|
||||
private final CompletionParameters myParameters;
|
||||
@@ -169,7 +150,7 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
CompletionParameters parameters,
|
||||
@NotNull CompletionSorterImpl sorter,
|
||||
@NotNull CompletionProgressIndicator process,
|
||||
CompletionResultSetImpl original) {
|
||||
@Nullable CompletionResultSetImpl original) {
|
||||
super(prefixMatcher, consumer, contributor);
|
||||
myTextBeforePosition = textBeforePosition;
|
||||
myParameters = parameters;
|
||||
@@ -290,34 +271,12 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
final CompletionLocation location = new CompletionLocation(parameters);
|
||||
|
||||
CompletionSorterImpl sorter = emptySorter();
|
||||
sorter = sorter.withClassifier(new ClassifierFactory<LookupElement>("startMatching") {
|
||||
@Override
|
||||
public Classifier<LookupElement> createClassifier(Classifier<LookupElement> next) {
|
||||
return new ComparingClassifier<LookupElement>(next, "startMatching") {
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable getWeight(LookupElement element) {
|
||||
return isMiddleMatch(element, location);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
sorter = sorter.withClassifier(new PreferStartMatching(location));
|
||||
|
||||
for (final Weigher weigher : WeighingService.getWeighers(CompletionService.RELEVANCE_KEY)) {
|
||||
final String id = weigher.toString();
|
||||
if ("prefix".equals(id)) {
|
||||
sorter = sorter.withClassifier(new ClassifierFactory<LookupElement>(id) {
|
||||
@Override
|
||||
public Classifier<LookupElement> createClassifier(Classifier<LookupElement> next) {
|
||||
return new ComparingClassifier<LookupElement>(next, id) {
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable getWeight(LookupElement element) {
|
||||
return -getPrefixMatchingDegree(element, location);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
sorter = sorter.withClassifier(new PrefixMatchingClassifier(id, location));
|
||||
}
|
||||
else {
|
||||
sorter = sorter.weigh(new LookupElementWeigher(id) {
|
||||
@@ -346,4 +305,52 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
public CompletionSorterImpl emptySorter() {
|
||||
return new CompletionSorterImpl(new ArrayList<ClassifierFactory<LookupElement>>());
|
||||
}
|
||||
|
||||
private static class PreferStartMatching extends ClassifierFactory<LookupElement> {
|
||||
private final CompletionLocation myLocation;
|
||||
|
||||
public PreferStartMatching(CompletionLocation location) {
|
||||
super("startMatching");
|
||||
myLocation = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Classifier<LookupElement> createClassifier(Classifier<LookupElement> next) {
|
||||
return new ComparingClassifier<LookupElement>(next, "startMatching") {
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable getWeight(LookupElement element) {
|
||||
PrefixMatcher itemMatcher = myLocation.getCompletionParameters().getLookup().itemMatcher(element);
|
||||
for (String ls : element.getAllLookupStrings()) {
|
||||
if (itemMatcher.isStartMatch(ls)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static class PrefixMatchingClassifier extends ClassifierFactory<LookupElement> {
|
||||
private final String myId;
|
||||
private final CompletionLocation myLocation;
|
||||
|
||||
public PrefixMatchingClassifier(String id, CompletionLocation location) {
|
||||
super(id);
|
||||
myId = id;
|
||||
myLocation = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Classifier<LookupElement> createClassifier(Classifier<LookupElement> next) {
|
||||
return new ComparingClassifier<LookupElement>(next, myId) {
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable getWeight(LookupElement element) {
|
||||
return -getPrefixMatchingDegree(element, myLocation);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.util.text.Matcher;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -287,7 +288,18 @@ public class MinusculeMatcher implements Matcher {
|
||||
return -fragmentCount + matchingCase * 10 + commonStart - startIndex + (prefixMatching ? 2 : middleWordStart ? 1 : 0) * 100;
|
||||
}
|
||||
|
||||
public static boolean isStartMatch(String name, int startIndex) {
|
||||
public boolean isStartMatch(String name) {
|
||||
Iterable<TextRange> fragments = matchingFragments(name);
|
||||
if (fragments != null) {
|
||||
Iterator<TextRange> iterator = fragments.iterator();
|
||||
if (!iterator.hasNext() || isStartMatch(name, iterator.next().getStartOffset())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isStartMatch(String name, int startIndex) {
|
||||
for (int i = 0; i < startIndex; i++) {
|
||||
if (!NameUtil.isWordSeparator(name.charAt(i))) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user