completion preselection: choose the most relevant among exact prefix items (IDEA-163441)

This commit is contained in:
peter
2016-11-21 16:41:08 +01:00
parent 8c8609b656
commit 53a517d779
3 changed files with 36 additions and 11 deletions
@@ -0,0 +1,6 @@
import pack2.SameNamed;
public class Usage {
private SameNamed<caret> f;
}
@@ -787,4 +787,13 @@ class ContainerUtil extends ContainerUtilRt {
checkPreferredItems 0, 'catch', 'finally'
}
void testPreselectClosestExactPrefixItem() {
UISettings.instance.SORT_LOOKUP_ELEMENTS_LEXICOGRAPHICALLY = true
myFixture.addClass 'package pack1; public class SameNamed {}'
myFixture.addClass 'package pack2; public class SameNamed {}'
checkPreferredItems 1, 'SameNamed', 'SameNamed'
assert LookupElementPresentation.renderElement(myFixture.lookupElements[0]).tailText.contains('pack1')
assert LookupElementPresentation.renderElement(myFixture.lookupElements[1]).tailText.contains('pack2')
}
}
@@ -39,6 +39,7 @@ import com.intellij.patterns.StandardPatterns;
import com.intellij.psi.statistics.StatisticsInfo;
import com.intellij.util.Alarm;
import com.intellij.util.ProcessingContext;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.containers.hash.EqualityPolicy;
@@ -391,31 +392,40 @@ public class CompletionLookupArranger extends LookupArranger {
}
}
LookupElement exactMatch = getBestExactMatch(lookup, items);
return Math.max(0, ContainerUtil.indexOfIdentity(items, exactMatch != null ? exactMatch : mostRelevant));
}
private List<LookupElement> getExactMatches(LookupImpl lookup, List<LookupElement> items) {
String selectedText = lookup.getTopLevelEditor().getSelectionModel().getSelectedText();
int exactMatchIndex = -1;
List<LookupElement> exactMatches = new SmartList<>();
for (int i = 0; i < items.size(); i++) {
LookupElement item = items.get(i);
boolean isSuddenLiveTemplate = isSuddenLiveTemplate(item);
if (isPrefixItem(item, true) && !isSuddenLiveTemplate || item.getLookupString().equals(selectedText)) {
if (item instanceof LiveTemplateLookupElement) {
// prefer most recent live template lookup item
exactMatchIndex = i;
break;
}
if (exactMatchIndex == -1) {
// prefer most recent item
exactMatchIndex = i;
return Collections.singletonList(item);
}
exactMatches.add(item);
}
else if (i == 0 && isSuddenLiveTemplate && items.size() > 1 && !CompletionServiceImpl.isStartMatch(items.get(1), this)) {
return 0;
return Collections.singletonList(item);
}
}
if (exactMatchIndex >= 0) {
return exactMatchIndex;
return exactMatches;
}
@Nullable
private LookupElement getBestExactMatch(LookupImpl lookup, List<LookupElement> items) {
List<LookupElement> exactMatches = getExactMatches(lookup, items);
if (exactMatches.isEmpty()) return null;
if (exactMatches.size() == 1) {
return exactMatches.get(0);
}
return Math.max(0, ContainerUtil.indexOfIdentity(items, mostRelevant));
return sortByRelevance(groupItemsBySorter(exactMatches)).iterator().next();
}
@Nullable