mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
introduce LookupArranger to support different sorting strategies in lookups
This commit is contained in:
+4
-4
@@ -11,12 +11,11 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.statistics.StatisticsManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class SkipAbstractExpectedTypeWeigher extends CompletionWeigher {
|
||||
public class SkipAbstractExpectedTypeWeigher extends CompletionPreselectSkipper {
|
||||
|
||||
enum Result {
|
||||
NON_DEFAULT,
|
||||
@@ -25,8 +24,9 @@ public class SkipAbstractExpectedTypeWeigher extends CompletionWeigher {
|
||||
ACCEPT
|
||||
}
|
||||
|
||||
public Comparable weigh(@NotNull final LookupElement item, final CompletionLocation location) {
|
||||
return getSkippingStatus(item, location);
|
||||
@Override
|
||||
public boolean skipElement(LookupElement element, CompletionLocation location) {
|
||||
return getSkippingStatus(element, location) != Result.ACCEPT;
|
||||
}
|
||||
|
||||
public static Result getSkippingStatus(final LookupElement item, final CompletionLocation location) {
|
||||
|
||||
+1
-1
@@ -374,7 +374,7 @@ public class ChangeSignatureDialog extends RefactoringDialog {
|
||||
LookupElement[] lookupItems = set.toArray(new LookupElement[set.size()]);
|
||||
editor.getCaretModel().moveToOffset(prefix.length());
|
||||
editor.getSelectionModel().removeSelection();
|
||||
LookupManager.getInstance(myProject).showLookup(editor, lookupItems, prefix, null);
|
||||
LookupManager.getInstance(myProject).showLookup(editor, lookupItems, prefix);
|
||||
}
|
||||
|
||||
private JComponent createSignaturePanel() {
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class CompletionPreselectSkipper {
|
||||
public static final ExtensionPointName<CompletionPreselectSkipper> EP_NAME = ExtensionPointName.create("com.intellij.completion.skip");
|
||||
|
||||
public abstract boolean skipElement(LookupElement element, CompletionLocation location);
|
||||
|
||||
}
|
||||
@@ -32,11 +32,6 @@ public abstract class CompletionService {
|
||||
* A "weigher" extension key (see {@link Weigher}) to sort completion items.
|
||||
*/
|
||||
public static final Key<CompletionWeigher> WEIGHER_KEY = Key.create("completion");
|
||||
/**
|
||||
* A "weigher" extension key (see {@link Weigher}) to skip some of the top lookup items that shouldn't be selected, but should still be at the top
|
||||
* (so {@link #WEIGHER_KEY} is not applicable).
|
||||
*/
|
||||
public static final Key<CompletionWeigher> PRESELECT_KEY = Key.create("preferredCompletionItem");
|
||||
|
||||
public static CompletionService getCompletionService() {
|
||||
return ServiceManager.getService(CompletionService.class);
|
||||
|
||||
+9
-6
@@ -13,8 +13,8 @@ import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.injected.editor.EditorWindow;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -28,8 +28,8 @@ import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
@@ -50,6 +50,9 @@ import com.intellij.util.concurrency.Semaphore;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.CodeCompletionHandlerBase");
|
||||
private final CompletionType myCompletionType;
|
||||
@@ -277,7 +280,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
|
||||
insertLookupString(context, offset2, uniqueText);
|
||||
context.editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
|
||||
lookupItemSelected(context, item, Lookup.AUTO_INSERT_SELECT_CHAR, items);
|
||||
lookupItemSelected(context, item, Lookup.AUTO_INSERT_SELECT_CHAR, Arrays.asList(items));
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
@@ -289,7 +292,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
|
||||
editor.getSelectionModel().removeSelection();
|
||||
}
|
||||
|
||||
protected static void selectLookupItem(final LookupElement item, final char completionChar, final CompletionContext context, final LookupElement[] items) {
|
||||
protected static void selectLookupItem(final LookupElement item, final char completionChar, final CompletionContext context, final List<LookupElement> items) {
|
||||
final int caretOffset = context.editor.getCaretModel().getOffset();
|
||||
|
||||
context.setSelectionEndOffset(caretOffset);
|
||||
@@ -413,10 +416,10 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
|
||||
}
|
||||
|
||||
private static void lookupItemSelected(final CompletionContext context, @NotNull final LookupElement item, final char completionChar,
|
||||
final LookupElement[] items) {
|
||||
final List<LookupElement> items) {
|
||||
final Editor editor = context.editor;
|
||||
final PsiFile file = context.file;
|
||||
final InsertionContext context1 = new InsertionContext(context.getOffsetMap(), completionChar, items, file, editor);
|
||||
final InsertionContext context1 = new InsertionContext(context.getOffsetMap(), completionChar, items.toArray(new LookupElement[items.size()]), file, editor);
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
final int idEndOffset = context.getOffsetMap().getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET);
|
||||
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.Lookup;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementDecorator;
|
||||
import com.intellij.codeInsight.lookup.LookupItem;
|
||||
import com.intellij.codeInsight.lookup.LookupArranger;
|
||||
import com.intellij.codeInsight.lookup.impl.LookupImpl;
|
||||
import com.intellij.codeInsight.lookup.impl.LookupItemWeightComparable;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.WeighingService;
|
||||
import com.intellij.psi.statistics.StatisticsInfo;
|
||||
import com.intellij.psi.statistics.StatisticsManager;
|
||||
import com.intellij.psi.util.proximity.PsiProximityComparator;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class CompletionLookupArranger extends LookupArranger {
|
||||
public static final Key<LookupItemWeightComparable> RELEVANCE_KEY = Key.create("RELEVANCE_KEY");
|
||||
@NonNls public static final String SELECTED = "selected";
|
||||
@NonNls public static final String IGNORED = "ignored";
|
||||
private final CompletionLocation myLocation;
|
||||
public static final Key<Comparable[]> WEIGHT = Key.create("WEIGHT");
|
||||
|
||||
public CompletionLookupArranger(final CompletionParameters parameters) {
|
||||
myLocation = new CompletionLocation(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sortItems(List<LookupElement> items) {
|
||||
final PsiProximityComparator proximityComparator = new PsiProximityComparator(myLocation.getCompletionParameters().getPosition());
|
||||
Collections.sort(items, new Comparator<LookupElement>() {
|
||||
public int compare(LookupElement o1, LookupElement o2) {
|
||||
LookupElement c1 = getCoreElement(o1);
|
||||
LookupElement c2 = getCoreElement(o2);
|
||||
|
||||
if (c1 instanceof LookupItem && c2 instanceof LookupItem) {
|
||||
double priority1 = ((LookupItem)c1).getPriority();
|
||||
double priority2 = ((LookupItem)c2).getPriority();
|
||||
if (priority1 > priority2) return -1;
|
||||
if (priority2 > priority1) return 1;
|
||||
}
|
||||
|
||||
int grouping1 = c1.getGrouping();
|
||||
int grouping2 = c2.getGrouping();
|
||||
if (grouping1 > grouping2) return -1;
|
||||
if (grouping2 > grouping1) return 1;
|
||||
|
||||
int stringCompare = o1.getLookupString().compareToIgnoreCase(o2.getLookupString());
|
||||
if (stringCompare != 0) return stringCompare;
|
||||
|
||||
return proximityComparator.compare(o1.getObject(), o2.getObject());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static LookupElement getCoreElement(LookupElement element) {
|
||||
while (element instanceof LookupElementDecorator) {
|
||||
element = ((LookupElementDecorator) element).getDelegate();
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
|
||||
public void itemSelected(LookupElement item, final Lookup lookup) {
|
||||
final StatisticsManager manager = StatisticsManager.getInstance();
|
||||
manager.incUseCount(CompletionService.STATISTICS_KEY, item, myLocation);
|
||||
final List<LookupElement> items = lookup.getItems();
|
||||
final LookupImpl lookupImpl = (LookupImpl)lookup;
|
||||
final int count = Math.min(lookupImpl.getPreferredItemsCount(), lookupImpl.getList().getSelectedIndex());
|
||||
for (int i = 0; i < count; i++) {
|
||||
final LookupElement element = items.get(i);
|
||||
StatisticsInfo info = StatisticsManager.serialize(CompletionService.STATISTICS_KEY, element, myLocation);
|
||||
if (info != null && info != StatisticsInfo.EMPTY && manager.getUseCount(info) == 0) {
|
||||
manager.incUseCount(new StatisticsInfo(composeContextWithValue(info), item == element ? SELECTED : IGNORED));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int suggestPreselectedItem(List<LookupElement> sorted) {
|
||||
final CompletionPreselectSkipper[] skippers = CompletionPreselectSkipper.EP_NAME.getExtensions();
|
||||
|
||||
nextItem: for (int i = 0; i < sorted.size(); i++){
|
||||
LookupElement item = sorted.get(i);
|
||||
final Object obj = item.getObject();
|
||||
if (obj instanceof PsiElement && !((PsiElement)obj).isValid()) continue;
|
||||
|
||||
for (final CompletionPreselectSkipper skipper : skippers) {
|
||||
if (skipper.skipElement(item, myLocation)) {
|
||||
continue nextItem;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
return sorted.size() - 1;
|
||||
}
|
||||
|
||||
public static String composeContextWithValue(final StatisticsInfo info) {
|
||||
return info.getContext() + "###" + info.getValue();
|
||||
}
|
||||
|
||||
public Comparable[] getWeight(final LookupElement item) {
|
||||
if (item.getUserData(WEIGHT) != null) return item.getUserData(WEIGHT);
|
||||
|
||||
final Comparable[] result = new Comparable[]{WeighingService.weigh(CompletionService.WEIGHER_KEY, item, myLocation)};
|
||||
|
||||
item.putUserData(WEIGHT, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static int doCompare(final double priority1, final double priority2, final Comparable[] weight1, final Comparable[] weight2) {
|
||||
if (priority1 != priority2) {
|
||||
final double v = priority1 - priority2;
|
||||
if (v > 0) return -1;
|
||||
if (v < 0) return 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < weight1.length; i++) {
|
||||
final Comparable w1 = weight1[i];
|
||||
final Comparable w2 = weight2[i];
|
||||
if (w1 != null || w2 != null) {
|
||||
if (w1 == null) return 1;
|
||||
if (w2 == null) return -1;
|
||||
//noinspection unchecked
|
||||
final int res = w1.compareTo(w2);
|
||||
if (res != 0) return -res;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LookupItemWeightComparable getRelevance(LookupElement item) {
|
||||
if (item.getUserData(RELEVANCE_KEY) != null) return item.getUserData(RELEVANCE_KEY);
|
||||
|
||||
final double priority = item instanceof LookupItem ? ((LookupItem)item).getPriority() : 0;
|
||||
final LookupItemWeightComparable result = new LookupItemWeightComparable(priority, getWeight(item));
|
||||
|
||||
item.putUserData(RELEVANCE_KEY, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
-100
@@ -1,100 +0,0 @@
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.Lookup;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupItem;
|
||||
import com.intellij.codeInsight.lookup.LookupItemPreferencePolicy;
|
||||
import com.intellij.codeInsight.lookup.impl.LookupImpl;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.psi.WeighingComparable;
|
||||
import com.intellij.psi.WeighingService;
|
||||
import com.intellij.psi.statistics.StatisticsInfo;
|
||||
import com.intellij.psi.statistics.StatisticsManager;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class CompletionPreferencePolicy implements LookupItemPreferencePolicy{
|
||||
public static final Key<WeighingComparable<LookupElement, CompletionLocation>> PRESELECT_WEIGHT = Key.create("PRESELECT_WEIGHT");
|
||||
@NonNls public static final String SELECTED = "selected";
|
||||
@NonNls public static final String IGNORED = "ignored";
|
||||
private final CompletionLocation myLocation;
|
||||
|
||||
public CompletionPreferencePolicy(final CompletionParameters parameters) {
|
||||
myLocation = new CompletionLocation(parameters);
|
||||
}
|
||||
|
||||
public void itemSelected(LookupElement item, final Lookup lookup) {
|
||||
final StatisticsManager manager = StatisticsManager.getInstance();
|
||||
manager.incUseCount(CompletionService.STATISTICS_KEY, item, myLocation);
|
||||
final LookupImpl lookupImpl = (LookupImpl)lookup;
|
||||
final ListModel model = lookupImpl.getList().getModel();
|
||||
final int count = Math.min(lookupImpl.getPreferredItemsCount(), lookupImpl.getList().getSelectedIndex());
|
||||
for (int i = 0; i < count; i++) {
|
||||
final LookupElement element = (LookupElement)model.getElementAt(i);
|
||||
StatisticsInfo info = StatisticsManager.serialize(CompletionService.STATISTICS_KEY, element, myLocation);
|
||||
if (info != null && info != StatisticsInfo.EMPTY && manager.getUseCount(info) == 0) {
|
||||
manager.incUseCount(new StatisticsInfo(composeContextWithValue(info), item == element ? SELECTED : IGNORED));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String composeContextWithValue(final StatisticsInfo info) {
|
||||
return info.getContext() + "###" + info.getValue();
|
||||
}
|
||||
|
||||
public Comparable[] getWeight(final LookupElement item) {
|
||||
if (item.getUserData(LookupItem.WEIGHT) != null) return item.getUserData(LookupItem.WEIGHT);
|
||||
|
||||
final Comparable[] result = new Comparable[]{WeighingService.weigh(CompletionService.WEIGHER_KEY, item, myLocation)};
|
||||
|
||||
item.putUserData(LookupItem.WEIGHT, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public int compare(final LookupElement item1, final LookupElement item2) {
|
||||
if (item1 == item2) return 0;
|
||||
|
||||
if (item1 instanceof LookupItem && item2 instanceof LookupItem) {
|
||||
double priority1 = ((LookupItem)item1).getPriority();
|
||||
double priority2 = ((LookupItem)item2).getPriority();
|
||||
if (priority1 > priority2) return -1;
|
||||
if (priority1 < priority2) return 1;
|
||||
}
|
||||
|
||||
return preselectWeigh(item2).compareTo(preselectWeigh(item1));
|
||||
}
|
||||
|
||||
private WeighingComparable<LookupElement, CompletionLocation> preselectWeigh(final LookupElement item) {
|
||||
WeighingComparable<LookupElement, CompletionLocation> data = item.getUserData(PRESELECT_WEIGHT);
|
||||
if (data == null) {
|
||||
item.putUserData(PRESELECT_WEIGHT, data = WeighingService.weigh(CompletionService.PRESELECT_KEY, item, myLocation));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public static int doCompare(final double priority1, final double priority2, final Comparable[] weight1, final Comparable[] weight2) {
|
||||
if (priority1 != priority2) {
|
||||
final double v = priority1 - priority2;
|
||||
if (v > 0) return -1;
|
||||
if (v < 0) return 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < weight1.length; i++) {
|
||||
final Comparable w1 = weight1[i];
|
||||
final Comparable w2 = weight2[i];
|
||||
if (w1 != null || w2 != null) {
|
||||
if (w1 == null) return 1;
|
||||
if (w2 == null) return -1;
|
||||
final int res = w1.compareTo(w2);
|
||||
if (res != 0) return -res;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
+1
-2
@@ -74,8 +74,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
myContextOriginal = contextOriginal;
|
||||
myFreezeSemaphore = freezeSemaphore;
|
||||
|
||||
myLookup = (LookupImpl)LookupManager.getInstance(editor.getProject()).createLookup(editor, new LookupItem[0], "", new CompletionPreferencePolicy(
|
||||
parameters));
|
||||
myLookup = (LookupImpl)LookupManager.getInstance(editor.getProject()).createLookup(editor, LookupElement.EMPTY_ARRAY, "", new CompletionLookupArranger(parameters));
|
||||
|
||||
myLookup.addLookupListener(new LookupAdapter() {
|
||||
public void itemSelected(LookupEvent event) {
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ public class NegativeStatisticsWeigher extends CompletionWeigher {
|
||||
final StatisticsInfo info = StatisticsManager.serialize(CompletionService.STATISTICS_KEY, item, location);
|
||||
if (info == null || info == StatisticsInfo.EMPTY) return 0;
|
||||
|
||||
final StatisticsInfo ignoreInfo = new StatisticsInfo(CompletionPreferencePolicy.composeContextWithValue(info), CompletionPreferencePolicy.IGNORED);
|
||||
final StatisticsInfo ignoreInfo = new StatisticsInfo(CompletionLookupArranger.composeContextWithValue(info), CompletionLookupArranger.IGNORED);
|
||||
final int count = manager.getUseCount(ignoreInfo);
|
||||
if (count >= StatisticsManager.OBLIVION_THRESHOLD - 1) {
|
||||
return -1;
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
|
||||
public interface Lookup extends UserDataHolder{
|
||||
char NORMAL_SELECT_CHAR = '\n';
|
||||
@@ -40,4 +41,6 @@ public interface Lookup extends UserDataHolder{
|
||||
PsiFile getPsiFile();
|
||||
|
||||
boolean isCompletion();
|
||||
|
||||
java.util.List<LookupElement> getItems();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.intellij.codeInsight.lookup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class LookupArranger {
|
||||
public static final LookupArranger DEFAULT = new LookupArranger() {
|
||||
@Override
|
||||
public Comparable getRelevance(LookupElement element) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sortItems(List<LookupElement> items) {
|
||||
}
|
||||
};
|
||||
|
||||
public abstract Comparable getRelevance(LookupElement element);
|
||||
|
||||
public void itemSelected(LookupElement item, final Lookup lookup) {
|
||||
}
|
||||
|
||||
public int suggestPreselectedItem(List<LookupElement> sorted) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public abstract void sortItems(List<LookupElement> items);
|
||||
}
|
||||
@@ -44,8 +44,6 @@ public class LookupItem<T> extends MutableLookupElement<T> implements Comparable
|
||||
public static final Object INDICATE_ANONYMOUS = Key.create("INDICATE ANONYMOUS");
|
||||
public static final Key<Object> DEPRECATED_ATTR = Key.create("DEPRECATED");
|
||||
|
||||
public static final Key<Comparable[]> WEIGHT = Key.create("WEIGHT");
|
||||
|
||||
public static final Object CASE_INSENSITIVE = Key.create("CASE_INSENSITIVE");
|
||||
|
||||
public static final Key<TailType> TAIL_TYPE_ATTR = Key.create("myTailType"); // one of constants defined in SimpleTailType interface
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.intellij.codeInsight.lookup;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
@@ -20,13 +21,16 @@ public abstract class LookupManager {
|
||||
return getInstance(project).getActiveLookup();
|
||||
}
|
||||
|
||||
public abstract Lookup showLookup(Editor editor, LookupElement[] items, LookupItemPreferencePolicy itemPreferencePolicy);
|
||||
@Deprecated
|
||||
public abstract Lookup showLookup(Editor editor, LookupElement[] items, LookupItemPreferencePolicy itemPreferencePolicy, @Nullable String bottomText);
|
||||
public abstract Lookup showLookup(Editor editor, LookupElement[] items, String prefix, LookupItemPreferencePolicy itemPreferencePolicy);
|
||||
@Deprecated
|
||||
public abstract Lookup showLookup(Editor editor, LookupElement[] items, String prefix, LookupItemPreferencePolicy itemPreferencePolicy,
|
||||
@Nullable String bottomText);
|
||||
public Lookup showLookup(Editor editor, @NotNull LookupElement... items) {
|
||||
return showLookup(editor, items, "", LookupArranger.DEFAULT);
|
||||
}
|
||||
|
||||
public Lookup showLookup(Editor editor, @NotNull LookupElement[] items, String prefix) {
|
||||
return showLookup(editor, items, prefix, LookupArranger.DEFAULT);
|
||||
}
|
||||
|
||||
public abstract Lookup showLookup(Editor editor, @NotNull LookupElement[] items, String prefix, @NotNull LookupArranger arranger);
|
||||
|
||||
public abstract void hideActiveLookup();
|
||||
public abstract Lookup getActiveLookup();
|
||||
|
||||
@@ -37,9 +41,6 @@ public abstract class LookupManager {
|
||||
|
||||
public abstract boolean isDisposed();
|
||||
|
||||
public abstract Lookup createLookup(Editor editor, LookupElement[] items, final String prefix, LookupItemPreferencePolicy itemPreferencePolicy);
|
||||
public abstract Lookup createLookup(Editor editor, @NotNull LookupElement[] items, final String prefix, LookupArranger arranger);
|
||||
|
||||
@Deprecated
|
||||
public abstract Lookup createLookup(Editor editor, LookupElement[] items, final String prefix, LookupItemPreferencePolicy itemPreferencePolicy,
|
||||
@Nullable String bottomText);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.intellij.codeInsight.lookup.impl;
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionPreferencePolicy;
|
||||
import com.intellij.codeInsight.completion.CompletionLookupArranger;
|
||||
import com.intellij.codeInsight.completion.PrefixMatcher;
|
||||
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
|
||||
import com.intellij.codeInsight.hint.HintManagerImpl;
|
||||
@@ -22,7 +22,6 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.proximity.PsiProximityComparator;
|
||||
import com.intellij.ui.LightweightHint;
|
||||
import com.intellij.ui.ListScrollingUtil;
|
||||
import com.intellij.ui.plaf.beg.BegPopupMenuBorder;
|
||||
@@ -33,6 +32,7 @@ import com.intellij.util.containers.ConcurrentHashMap;
|
||||
import com.intellij.util.containers.SortedList;
|
||||
import com.intellij.util.ui.AsyncProcessIcon;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
@@ -53,8 +53,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
|
||||
private final Project myProject;
|
||||
private final Editor myEditor;
|
||||
private final SortedList<LookupElement> myItems;
|
||||
private final SortedMap<LookupItemWeightComparable, SortedList<LookupElement>> myItemsMap;
|
||||
|
||||
private final Map<LookupElement, Collection<LookupElementAction>> myItemActions = new ConcurrentHashMap<LookupElement, Collection<LookupElementAction>>();
|
||||
private int myMinPrefixLength;
|
||||
private int myPreferredItemsCount;
|
||||
@@ -62,7 +61,9 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
private RangeMarker myInitialSelection;
|
||||
private long myShownStamp = -1;
|
||||
private String myInitialPrefix;
|
||||
@Nullable private final LookupItemPreferencePolicy myItemPreferencePolicy;
|
||||
private final LookupArranger myArranger;
|
||||
private final ArrayList<LookupElement> myItems;
|
||||
@Nullable private List<LookupElement> mySortedItems;
|
||||
|
||||
private RangeMarker myLookupStartMarker;
|
||||
private int myOldLookupStartOffset;
|
||||
@@ -81,63 +82,28 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
private LookupElement myPreselectedItem = EMPTY_LOOKUP_ITEM;
|
||||
private boolean myDirty;
|
||||
private String myAdditionalPrefix = "";
|
||||
private final PsiElement myElement;
|
||||
private final AsyncProcessIcon myProcessIcon;
|
||||
private final Comparator<LookupElement> myComparator;
|
||||
private volatile boolean myCalculating;
|
||||
private final JLabel myAdComponent;
|
||||
private volatile String myAdText;
|
||||
private volatile int myLookupWidth = 50;
|
||||
private static final int LOOKUP_HEIGHT = Integer.getInteger("idea.lookup.height", 11).intValue();
|
||||
|
||||
public LookupImpl(Project project, Editor editor, LookupElement[] items, @Nullable LookupItemPreferencePolicy itemPreferencePolicy){
|
||||
public LookupImpl(Project project, Editor editor, @NotNull LookupArranger arranger){
|
||||
super(new JPanel(new BorderLayout()));
|
||||
myProject = project;
|
||||
myEditor = editor;
|
||||
myItemPreferencePolicy = itemPreferencePolicy;
|
||||
myArranger = arranger;
|
||||
myItems = new ArrayList<LookupElement>();
|
||||
|
||||
setInitialOffset(myEditor.getCaretModel().getOffset(), myEditor.getSelectionModel().getSelectionStart(), myEditor.getSelectionModel().getSelectionEnd());
|
||||
|
||||
final Document document = myEditor.getDocument();
|
||||
final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
|
||||
myElement = psiFile == null ? null : psiFile.findElementAt(myEditor.getCaretModel().getOffset());
|
||||
|
||||
final PsiProximityComparator proximityComparator = new PsiProximityComparator(myElement == null ? psiFile : myElement);
|
||||
myComparator = new Comparator<LookupElement>() {
|
||||
public int compare(LookupElement o1, LookupElement o2) {
|
||||
LookupElement c1 = getCoreElement(o1);
|
||||
LookupElement c2 = getCoreElement(o2);
|
||||
|
||||
if (c1 instanceof LookupItem && c2 instanceof LookupItem) {
|
||||
double priority1 = ((LookupItem)c1).getPriority();
|
||||
double priority2 = ((LookupItem)c2).getPriority();
|
||||
if (priority1 > priority2) return -1;
|
||||
if (priority2 > priority1) return 1;
|
||||
}
|
||||
|
||||
int grouping1 = c1.getGrouping();
|
||||
int grouping2 = c2.getGrouping();
|
||||
if (grouping1 > grouping2) return -1;
|
||||
if (grouping2 > grouping1) return 1;
|
||||
|
||||
int stringCompare = o1.getLookupString().compareToIgnoreCase(o2.getLookupString());
|
||||
if (stringCompare != 0) return stringCompare;
|
||||
|
||||
return proximityComparator.compare(o1.getObject(), o2.getObject());
|
||||
}
|
||||
};
|
||||
myItems = new SortedList<LookupElement>(myComparator);
|
||||
myItemsMap = new TreeMap<LookupItemWeightComparable, SortedList<LookupElement>>();
|
||||
|
||||
myProcessIcon = new AsyncProcessIcon("Completion progress");
|
||||
myProcessIcon.setVisible(false);
|
||||
myList = new JList(new DefaultListModel());
|
||||
myCellRenderer = new LookupCellRenderer(this);
|
||||
myList.setCellRenderer(myCellRenderer);
|
||||
|
||||
for (final LookupElement item : items) {
|
||||
addItem(item);
|
||||
}
|
||||
|
||||
myList.setFocusable(false);
|
||||
|
||||
myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
@@ -156,15 +122,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
getComponent().add(bottomPanel, BorderLayout.SOUTH);
|
||||
getComponent().setBorder(new BegPopupMenuBorder());
|
||||
|
||||
updateList();
|
||||
selectMostPreferableItem();
|
||||
}
|
||||
|
||||
private LookupElement getCoreElement(LookupElement element) {
|
||||
while (element instanceof LookupElementDecorator) {
|
||||
element = ((LookupElementDecorator) element).getDelegate();
|
||||
}
|
||||
return element;
|
||||
updateListBounds();
|
||||
}
|
||||
|
||||
public AsyncProcessIcon getProcessIcon() {
|
||||
@@ -190,11 +148,14 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
|
||||
@TestOnly
|
||||
public void resort() {
|
||||
final ArrayList<LookupElement> items = new ArrayList<LookupElement>(myItems);
|
||||
myDirty = false;
|
||||
myPreselectedItem = EMPTY_LOOKUP_ITEM;
|
||||
myItemsMap.clear();
|
||||
myItems.clear();
|
||||
final ArrayList<LookupElement> items;
|
||||
synchronized (myItems) {
|
||||
items = new ArrayList<LookupElement>(myItems);
|
||||
myItems.clear();
|
||||
mySortedItems = null;
|
||||
}
|
||||
for (final LookupElement item : items) {
|
||||
addItem(item);
|
||||
}
|
||||
@@ -202,27 +163,19 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
}
|
||||
|
||||
public void addItem(LookupElement item) {
|
||||
final double priority = item instanceof LookupItem ? ((LookupItem)item).getPriority() : 0;
|
||||
final Comparable[] weight = getWeight(myItemPreferencePolicy, myElement, item);
|
||||
final LookupItemWeightComparable comparable = new LookupItemWeightComparable(priority, weight);
|
||||
|
||||
final CollectConsumer<LookupElementAction> consumer = new CollectConsumer<LookupElementAction>();
|
||||
for (LookupActionProvider provider : LookupActionProvider.EP_NAME.getExtensions()) {
|
||||
provider.fillActions(item, this, consumer);
|
||||
}
|
||||
myItemActions.put(item, consumer.getResult());
|
||||
|
||||
synchronized (myItems) {
|
||||
myItems.add(item);
|
||||
|
||||
SortedList<LookupElement> list = myItemsMap.get(comparable);
|
||||
if (list == null) {
|
||||
myItemsMap.put(comparable, list = new SortedList<LookupElement>(myComparator));
|
||||
}
|
||||
list.add(item);
|
||||
}
|
||||
int maxWidth = myCellRenderer.updateMaximumWidth(item);
|
||||
myLookupWidth = Math.max(maxWidth, myLookupWidth);
|
||||
|
||||
synchronized (myItems) {
|
||||
myItems.add(item);
|
||||
mySortedItems = null;
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<LookupElementAction> getActionsFor(LookupElement element) {
|
||||
@@ -230,23 +183,6 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
return collection == null ? Collections.<LookupElementAction>emptyList() : collection;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public LookupItemPreferencePolicy getItemPreferencePolicy() {
|
||||
return myItemPreferencePolicy;
|
||||
}
|
||||
|
||||
private static Comparable[] getWeight(final LookupItemPreferencePolicy itemPreferencePolicy, final PsiElement context,
|
||||
final LookupElement item) {
|
||||
if (itemPreferencePolicy instanceof CompletionPreferencePolicy) {
|
||||
return ((CompletionPreferencePolicy)itemPreferencePolicy).getWeight(item);
|
||||
}
|
||||
Comparable i = null;
|
||||
if (item.getObject() instanceof PsiElement) {
|
||||
i = PsiProximityComparator.getProximity((PsiElement)item.getObject(), context);
|
||||
}
|
||||
return new Comparable[]{i};
|
||||
}
|
||||
|
||||
public int getMinPrefixLength() {
|
||||
return myMinPrefixLength;
|
||||
}
|
||||
@@ -255,12 +191,32 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
return myList;
|
||||
}
|
||||
|
||||
public LookupElement[] getItems(){
|
||||
@NotNull
|
||||
private List<LookupElement> getSortedItems() {
|
||||
synchronized (myItems) {
|
||||
return myItems.toArray(new LookupElement[myItems.size()]);
|
||||
List<LookupElement> sortedItems = mySortedItems;
|
||||
if (sortedItems == null) {
|
||||
myArranger.sortItems(sortedItems = new ArrayList<LookupElement>(myItems));
|
||||
mySortedItems = sortedItems;
|
||||
}
|
||||
return sortedItems;
|
||||
}
|
||||
}
|
||||
|
||||
public List<LookupElement> getItems() {
|
||||
final ArrayList<LookupElement> result = new ArrayList<LookupElement>();
|
||||
final Object[] objects;
|
||||
synchronized (myList) {
|
||||
objects = ((DefaultListModel)myList.getModel()).toArray();
|
||||
}
|
||||
for (final Object object : objects) {
|
||||
if (!(object instanceof EmptyLookupItem)) {
|
||||
result.add((LookupElement) object);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setAdvertisementText(@Nullable String text) {
|
||||
myAdText = text;
|
||||
}
|
||||
@@ -282,69 +238,80 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
}
|
||||
|
||||
private void updateList() {
|
||||
synchronized (myItems) {
|
||||
int minPrefixLength = myItems.isEmpty() ? 0 : Integer.MAX_VALUE;
|
||||
for (final LookupElement item : myItems) {
|
||||
minPrefixLength = Math.min(item.getPrefixMatcher().getPrefix().length(), minPrefixLength);
|
||||
}
|
||||
if (myMinPrefixLength != minPrefixLength) {
|
||||
myLookupStartMarker = null;
|
||||
myOldLookupStartOffset = -1;
|
||||
}
|
||||
myMinPrefixLength = minPrefixLength;
|
||||
final List<LookupElement> items = getSortedItems();
|
||||
SortedMap<Comparable, List<LookupElement>> itemsMap = new TreeMap<Comparable, List<LookupElement>>();
|
||||
int minPrefixLength = items.isEmpty() ? 0 : Integer.MAX_VALUE;
|
||||
for (final LookupElement item : items) {
|
||||
minPrefixLength = Math.min(item.getPrefixMatcher().getPrefix().length(), minPrefixLength);
|
||||
|
||||
Object oldSelected = !myDirty ? null : myList.getSelectedValue();
|
||||
final Comparable relevance = myArranger.getRelevance(item);
|
||||
List<LookupElement> list = itemsMap.get(relevance);
|
||||
if (list == null) {
|
||||
itemsMap.put(relevance, list = new ArrayList<LookupElement>());
|
||||
}
|
||||
list.add(item);
|
||||
}
|
||||
|
||||
if (myMinPrefixLength != minPrefixLength) {
|
||||
myLookupStartMarker = null;
|
||||
myOldLookupStartOffset = -1;
|
||||
}
|
||||
myMinPrefixLength = minPrefixLength;
|
||||
|
||||
Object oldSelected = !myDirty ? null : myList.getSelectedValue();
|
||||
boolean hasExactPrefixes;
|
||||
final boolean hasPreselectedItem;
|
||||
synchronized (myList) {
|
||||
DefaultListModel model = (DefaultListModel)myList.getModel();
|
||||
model.clear();
|
||||
|
||||
Set<LookupElement> firstItems = new THashSet<LookupElement>();
|
||||
|
||||
addExactPrefixItems(model, firstItems);
|
||||
|
||||
boolean hasExactPrefixes = !firstItems.isEmpty();
|
||||
|
||||
addMostRelevantItems(model, firstItems);
|
||||
|
||||
final boolean hasPreselectedItem = addPreselectedItem(model, firstItems);
|
||||
|
||||
hasExactPrefixes = addExactPrefixItems(model, firstItems, items);
|
||||
addMostRelevantItems(model, firstItems, itemsMap.values());
|
||||
hasPreselectedItem = addPreselectedItem(model, firstItems);
|
||||
myPreferredItemsCount = firstItems.size();
|
||||
|
||||
addRemainingItemsLexicographically(model, firstItems);
|
||||
addRemainingItemsLexicographically(model, firstItems, items);
|
||||
}
|
||||
|
||||
boolean isEmpty = model.getSize() == 0;
|
||||
if (isEmpty) {
|
||||
addEmptyItem(model);
|
||||
} else {
|
||||
myList.setFixedCellWidth(myLookupWidth);
|
||||
updateListBounds();
|
||||
|
||||
myAdComponent.setText(myAdText);
|
||||
|
||||
if (myList.getModel().getSize() > 0) {
|
||||
if (oldSelected != null) {
|
||||
if (hasExactPrefixes || !ListScrollingUtil.selectItem(myList, oldSelected)) {
|
||||
selectMostPreferableItem();
|
||||
}
|
||||
}
|
||||
myList.setFixedCellHeight(myCellRenderer.getListCellRendererComponent(myList, myList.getModel().getElementAt(0), 0, false, false).getPreferredSize().height);
|
||||
|
||||
myList.setVisibleRowCount(Math.min(myList.getModel().getSize(), LOOKUP_HEIGHT));
|
||||
|
||||
myAdComponent.setText(myAdText);
|
||||
|
||||
if (!isEmpty) {
|
||||
if (oldSelected != null) {
|
||||
if (hasExactPrefixes || !ListScrollingUtil.selectItem(myList, oldSelected)) {
|
||||
selectMostPreferableItem();
|
||||
}
|
||||
else {
|
||||
if (myPreselectedItem == EMPTY_LOOKUP_ITEM) {
|
||||
selectMostPreferableItem();
|
||||
myPreselectedItem = getCurrentItem();
|
||||
}
|
||||
else if (hasPreselectedItem && !hasExactPrefixes) {
|
||||
ListScrollingUtil.selectItem(myList, myPreselectedItem);
|
||||
}
|
||||
else {
|
||||
if (myPreselectedItem == EMPTY_LOOKUP_ITEM) {
|
||||
selectMostPreferableItem();
|
||||
myPreselectedItem = getCurrentItem();
|
||||
}
|
||||
else if (hasPreselectedItem && !hasExactPrefixes) {
|
||||
ListScrollingUtil.selectItem(myList, myPreselectedItem);
|
||||
}
|
||||
else {
|
||||
selectMostPreferableItem();
|
||||
}
|
||||
selectMostPreferableItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateListBounds() {
|
||||
final ListModel model = myList.getModel();
|
||||
if (model.getSize() == 0) {
|
||||
addEmptyItem((DefaultListModel)model);
|
||||
} else {
|
||||
myList.setFixedCellWidth(myLookupWidth);
|
||||
}
|
||||
myList.setFixedCellHeight(myCellRenderer.getListCellRendererComponent(myList, model.getElementAt(0), 0, false, false).getPreferredSize().height);
|
||||
|
||||
myList.setVisibleRowCount(Math.min(model.getSize(), LOOKUP_HEIGHT));
|
||||
}
|
||||
|
||||
private void addEmptyItem(DefaultListModel model) {
|
||||
LookupItem<String> item = new EmptyLookupItem(myCalculating ? " " : LangBundle.message("completion.no.suggestions"));
|
||||
item.setPrefixMatcher(new CamelHumpMatcher(""));
|
||||
@@ -356,7 +323,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
model.addElement(item);
|
||||
}
|
||||
|
||||
private void addRemainingItemsLexicographically(DefaultListModel model, Set<LookupElement> firstItems) {
|
||||
private void addRemainingItemsLexicographically(DefaultListModel model, Set<LookupElement> firstItems, List<LookupElement> myItems) {
|
||||
for (LookupElement item : myItems) {
|
||||
if (!firstItems.contains(item) && prefixMatches(item)) {
|
||||
model.addElement(item);
|
||||
@@ -373,10 +340,10 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
return hasPreselectedItem;
|
||||
}
|
||||
|
||||
private void addMostRelevantItems(DefaultListModel model, Set<LookupElement> firstItems) {
|
||||
for (final LookupItemWeightComparable comparable : myItemsMap.keySet()) {
|
||||
private void addMostRelevantItems(DefaultListModel model, Set<LookupElement> firstItems, final Collection<List<LookupElement>> sortedItems) {
|
||||
for (final List<LookupElement> elements : sortedItems) {
|
||||
final List<LookupElement> suitable = new SmartList<LookupElement>();
|
||||
for (final LookupElement item : myItemsMap.get(comparable)) {
|
||||
for (final LookupElement item : elements) {
|
||||
if (!firstItems.contains(item) && prefixMatches(item)) {
|
||||
suitable.add(item);
|
||||
}
|
||||
@@ -390,15 +357,29 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private void addExactPrefixItems(DefaultListModel model, Set<LookupElement> firstItems) {
|
||||
for (final LookupItemWeightComparable comparable : myItemsMap.keySet()) {
|
||||
for (final LookupElement item : myItemsMap.get(comparable)) {
|
||||
if (isExactPrefixItem(item)) {
|
||||
model.addElement(item);
|
||||
firstItems.add(item);
|
||||
}
|
||||
private boolean addExactPrefixItems(DefaultListModel model, Set<LookupElement> firstItems, final List<LookupElement> elements) {
|
||||
List<LookupElement> sorted = new SortedList<LookupElement>(new Comparator<LookupElement>() {
|
||||
public int compare(LookupElement o1, LookupElement o2) {
|
||||
//noinspection unchecked
|
||||
return myArranger.getRelevance(o1).compareTo(myArranger.getRelevance(o2));
|
||||
}
|
||||
});
|
||||
for (final LookupElement item : elements) {
|
||||
if (isExactPrefixItem(item)) {
|
||||
sorted.add(item);
|
||||
|
||||
}
|
||||
}
|
||||
for (final LookupElement item : sorted) {
|
||||
model.addElement(item);
|
||||
firstItems.add(item);
|
||||
}
|
||||
|
||||
return !firstItems.isEmpty();
|
||||
}
|
||||
|
||||
private boolean isExactPrefixItem(LookupElement item) {
|
||||
return item.getAllLookupStrings().contains(item.getPrefixMatcher().getPrefix() + myAdditionalPrefix);
|
||||
}
|
||||
|
||||
private boolean prefixMatches(final LookupElement item) {
|
||||
@@ -424,9 +405,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
JComponent internalComponent = myEditor.getContentComponent();
|
||||
final JRootPane rootPane = editorComponent.getRootPane();
|
||||
if (rootPane == null) {
|
||||
synchronized (myItems) {
|
||||
LOG.assertTrue(false, myItems);
|
||||
}
|
||||
LOG.assertTrue(false, myArranger);
|
||||
}
|
||||
JLayeredPane layeredPane = rootPane.getLayeredPane();
|
||||
Point layeredPanePoint=SwingUtilities.convertPoint(internalComponent,location, layeredPane);
|
||||
@@ -621,14 +600,15 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
return Math.max(offset - myMinPrefixLength, 0);
|
||||
}
|
||||
|
||||
private void selectMostPreferableItem(){
|
||||
final int index = doSelectMostPreferableItem(((DefaultListModel)myList.getModel()).toArray());
|
||||
private void selectMostPreferableItem() {
|
||||
final List<LookupElement> sortedItems = getItems();
|
||||
final int index = doSelectMostPreferableItem(sortedItems);
|
||||
myList.setSelectedIndex(index);
|
||||
|
||||
if (index >= 0 && index < myList.getModel().getSize()){
|
||||
ListScrollingUtil.selectItem(myList, index);
|
||||
}
|
||||
else if (!myItems.isEmpty()) {
|
||||
else if (!sortedItems.isEmpty()) {
|
||||
ListScrollingUtil.selectItem(myList, 0);
|
||||
}
|
||||
}
|
||||
@@ -666,8 +646,8 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
public void fireItemSelected(final LookupElement item, char completionChar){
|
||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
||||
|
||||
if (item != null && myItemPreferencePolicy != null){
|
||||
myItemPreferencePolicy.itemSelected(item, this);
|
||||
if (item != null) {
|
||||
myArranger.itemSelected(item, this);
|
||||
}
|
||||
|
||||
if (!myListeners.isEmpty()){
|
||||
@@ -787,14 +767,16 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
|
||||
final String newPrefix = presentPrefix + afterCaret;
|
||||
synchronized (myItems) {
|
||||
for (Iterator<LookupElement> it = myItems.iterator(); it.hasNext();) {
|
||||
LookupElement item = it.next();
|
||||
for (Iterator<LookupElement> iterator = myItems.iterator(); iterator.hasNext();) {
|
||||
LookupElement item = iterator.next();
|
||||
if (!item.setPrefixMatcher(item.getPrefixMatcher().cloneWithPrefix(newPrefix))) {
|
||||
it.remove();
|
||||
iterator.remove();
|
||||
mySortedItems = null;
|
||||
}
|
||||
}
|
||||
myAdditionalPrefix = "";
|
||||
}
|
||||
myAdditionalPrefix = "";
|
||||
myAdditionalPrefix = "";
|
||||
updateList();
|
||||
|
||||
offset += afterCaret.length();
|
||||
@@ -813,7 +795,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
}
|
||||
|
||||
public boolean isCompletion() {
|
||||
return myItemPreferencePolicy instanceof CompletionPreferencePolicy;
|
||||
return myArranger instanceof CompletionLookupArranger;
|
||||
}
|
||||
|
||||
public PsiElement getPsiElement() {
|
||||
@@ -877,36 +859,25 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private int doSelectMostPreferableItem(Object[] items) {
|
||||
if (myItemPreferencePolicy == null){
|
||||
private int doSelectMostPreferableItem(List<LookupElement> items) {
|
||||
if (items.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int prefItemIndex = -1;
|
||||
if (items.size() == 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(int i = 0; i < items.length; i++){
|
||||
LookupElement item = (LookupElement)items[i];
|
||||
final Object obj = item.getObject();
|
||||
if (obj instanceof PsiElement && !((PsiElement)obj).isValid()) continue;
|
||||
|
||||
if (prefItemIndex == -1) {
|
||||
prefItemIndex = i;
|
||||
}
|
||||
else {
|
||||
int d = myItemPreferencePolicy.compare(item, (LookupElement)items[prefItemIndex]);
|
||||
if (d < 0) {
|
||||
prefItemIndex = i;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
LookupElement item = items.get(i);
|
||||
if (isExactPrefixItem(item)) {
|
||||
break;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return prefItemIndex;
|
||||
}
|
||||
|
||||
private boolean isExactPrefixItem(LookupElement item) {
|
||||
return item.getAllLookupStrings().contains(item.getPrefixMatcher().getPrefix() + myAdditionalPrefix);
|
||||
final int index = myArranger.suggestPreselectedItem(items);
|
||||
assert index >= 0 && index < items.size();
|
||||
return index;
|
||||
}
|
||||
|
||||
public void refreshUi() {
|
||||
@@ -925,12 +896,8 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
public LookupElement[] getSortedItems() {
|
||||
synchronized (myItems) {
|
||||
final LookupElement[] result = new LookupElement[myList.getModel().getSize()];
|
||||
((DefaultListModel)myList.getModel()).copyInto(result);
|
||||
return result;
|
||||
}
|
||||
@TestOnly
|
||||
public LookupArranger getLookupModel() {
|
||||
return myArranger;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.lookup.impl;
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionPreferencePolicy;
|
||||
import com.intellij.codeInsight.completion.CompletionLookupArranger;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -20,7 +20,7 @@ public class LookupItemWeightComparable implements Comparable<LookupItemWeightCo
|
||||
}
|
||||
|
||||
public int compareTo(final LookupItemWeightComparable o) {
|
||||
return CompletionPreferencePolicy.doCompare(myPriority, o.myPriority, myWeight, o.myWeight);
|
||||
return CompletionLookupArranger.doCompare(myPriority, o.myPriority, myWeight, o.myWeight);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
||||
+13
-31
@@ -21,7 +21,6 @@ import com.intellij.ui.LightweightHint;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
@@ -96,36 +95,13 @@ public class LookupManagerImpl extends LookupManager implements ProjectComponent
|
||||
myIsDisposed = true;
|
||||
}
|
||||
|
||||
public Lookup showLookup(final Editor editor, LookupElement[] items, LookupItemPreferencePolicy itemPreferencePolicy) {
|
||||
return showLookup(editor, items, "", itemPreferencePolicy);
|
||||
}
|
||||
|
||||
public Lookup showLookup(Editor editor,
|
||||
LookupElement[] items,
|
||||
LookupItemPreferencePolicy itemPreferencePolicy,
|
||||
@Nullable String bottomText) {
|
||||
return showLookup(editor, items, itemPreferencePolicy);
|
||||
}
|
||||
|
||||
public Lookup showLookup(final Editor editor, final LookupElement[] items, final String prefix, final LookupItemPreferencePolicy itemPreferencePolicy) {
|
||||
final LookupImpl lookup = createLookup(editor, items, prefix, itemPreferencePolicy);
|
||||
public Lookup showLookup(final Editor editor, @NotNull LookupElement[] items, final String prefix, @NotNull final LookupArranger arranger) {
|
||||
final LookupImpl lookup = createLookup(editor, items, prefix, arranger);
|
||||
lookup.show();
|
||||
return lookup;
|
||||
}
|
||||
|
||||
public Lookup showLookup(Editor editor,
|
||||
LookupElement[] items,
|
||||
String prefix,
|
||||
LookupItemPreferencePolicy itemPreferencePolicy,
|
||||
@Nullable String bottomText) {
|
||||
return showLookup(editor, items, prefix, itemPreferencePolicy);
|
||||
}
|
||||
|
||||
public LookupImpl createLookup(final Editor editor, final LookupElement[] items, final String prefix, final LookupItemPreferencePolicy itemPreferencePolicy) {
|
||||
return createLookup(editor, items, prefix, itemPreferencePolicy, null);
|
||||
}
|
||||
|
||||
public LookupImpl createLookup(final Editor editor, LookupElement[] items, String prefix, LookupItemPreferencePolicy itemPreferencePolicy, @Nullable String bottomText) {
|
||||
public LookupImpl createLookup(final Editor editor, @NotNull LookupElement[] items, final String prefix, @NotNull final LookupArranger arranger) {
|
||||
hideActiveLookup();
|
||||
|
||||
final CodeInsightSettings settings = CodeInsightSettings.getInstance();
|
||||
@@ -146,10 +122,7 @@ public class LookupManagerImpl extends LookupManager implements ProjectComponent
|
||||
if (daemonCodeAnalyzer != null) {
|
||||
daemonCodeAnalyzer.setUpdateByTimerEnabled(false);
|
||||
}
|
||||
for (final LookupElement item : items) {
|
||||
item.setPrefixMatcher(new CamelHumpMatcher(prefix));
|
||||
}
|
||||
myActiveLookup = new LookupImpl(myProject, editor, items, itemPreferencePolicy);
|
||||
myActiveLookup = new LookupImpl(myProject, editor, arranger);
|
||||
myActiveLookupEditor = editor;
|
||||
myActiveLookup.addLookupListener(
|
||||
new LookupAdapter(){
|
||||
@@ -182,6 +155,15 @@ public class LookupManagerImpl extends LookupManager implements ProjectComponent
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (items.length > 0) {
|
||||
for (final LookupElement item : items) {
|
||||
item.setPrefixMatcher(new CamelHumpMatcher(prefix));
|
||||
myActiveLookup.addItem(item);
|
||||
}
|
||||
myActiveLookup.refreshUi();
|
||||
}
|
||||
|
||||
myPropertyChangeSupport.firePropertyChange(PROP_ACTIVE_LOOKUP, null, myActiveLookup);
|
||||
return myActiveLookup;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package com.intellij.codeInsight.lookup.impl;
|
||||
|
||||
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
|
||||
import com.intellij.codeInsight.lookup.Lookup;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupItemPreferencePolicy;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
|
||||
@@ -16,28 +12,13 @@ import com.intellij.util.messages.MessageBus;
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public class TestLookupManager extends LookupManagerImpl{
|
||||
private final Project myProject;
|
||||
public TestLookupManager(Project project, MessageBus bus){
|
||||
super(project, bus);
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
public Lookup showLookup(final Editor editor, LookupElement[] items, LookupItemPreferencePolicy itemPreferencePolicy) {
|
||||
hideActiveLookup();
|
||||
|
||||
for (final LookupElement item : items) {
|
||||
item.setPrefixMatcher(new CamelHumpMatcher(""));
|
||||
}
|
||||
myActiveLookup = new LookupImpl(myProject, editor, items, itemPreferencePolicy);
|
||||
myActiveLookupEditor = editor;
|
||||
myActiveLookup.show();
|
||||
return myActiveLookup;
|
||||
}
|
||||
|
||||
public void forceSelection(char completion, int index){
|
||||
if(myActiveLookup == null) throw new RuntimeException("There are no items in this lookup");
|
||||
final LookupElement[] items = myActiveLookup.getItems();
|
||||
final LookupElement lookupItem = items[index];
|
||||
final LookupElement lookupItem = myActiveLookup.getItems().get(index);
|
||||
myActiveLookup.setCurrentItem(lookupItem);
|
||||
myActiveLookup.finishLookup(completion);
|
||||
}
|
||||
@@ -54,7 +35,4 @@ public class TestLookupManager extends LookupManagerImpl{
|
||||
}
|
||||
}
|
||||
|
||||
public LookupElement[] getItems(){
|
||||
return myActiveLookup != null ? myActiveLookup.getItems() : null;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ public class ListTemplatesHandler implements CodeInsightActionHandler{
|
||||
return;
|
||||
}
|
||||
|
||||
final LookupImpl lookup = (LookupImpl) LookupManager.getInstance(project).createLookup(editor, items, prefix, null);
|
||||
final LookupImpl lookup = (LookupImpl) LookupManager.getInstance(project).createLookup(editor, items, prefix, LookupArranger.DEFAULT);
|
||||
lookup.addLookupListener(
|
||||
new LookupAdapter() {
|
||||
public void itemSelected(LookupEvent event) {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.intellij.codeInsight.template.impl;
|
||||
|
||||
import com.intellij.codeInsight.AutoPopupController;
|
||||
import com.intellij.codeInsight.completion.*;
|
||||
import com.intellij.codeInsight.completion.CompletionInitializationContext;
|
||||
import com.intellij.codeInsight.completion.InsertionContext;
|
||||
import com.intellij.codeInsight.completion.OffsetMap;
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
import com.intellij.codeInsight.template.*;
|
||||
import com.intellij.lang.LanguageLiteralEscapers;
|
||||
@@ -23,8 +25,8 @@ import com.intellij.openapi.editor.ex.DocumentEx;
|
||||
import com.intellij.openapi.editor.markup.*;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -400,9 +402,6 @@ public class TemplateState implements Disposable {
|
||||
EditorModificationUtil.insertStringAtCaret(myEditor, s);
|
||||
itemSelected(lookupItems[0], psiFile, currentSegmentNumber, ' ', lookupItems);
|
||||
} else {
|
||||
if (lookupItems[0] instanceof LookupItem) {
|
||||
((LookupItem)lookupItems[0]).setPriority(Integer.MAX_VALUE);
|
||||
}
|
||||
runLookup(currentSegmentNumber, lookupItems, psiFile);
|
||||
}
|
||||
}
|
||||
@@ -422,9 +421,7 @@ public class TemplateState implements Disposable {
|
||||
final LookupManager lookupManager = LookupManager.getInstance(myProject);
|
||||
if (lookupManager.isDisposed()) return;
|
||||
|
||||
final CompletionParameters parameters =
|
||||
new CompletionParameters(psiFile, psiFile, CompletionType.BASIC, myEditor.getCaretModel().getOffset(), 1);
|
||||
final Lookup lookup = lookupManager.showLookup(myEditor, lookupItems, new CompletionPreferencePolicy(parameters));
|
||||
final Lookup lookup = lookupManager.showLookup(myEditor, lookupItems);
|
||||
toProcessTab = false;
|
||||
lookup.addLookupListener(new LookupAdapter() {
|
||||
public void lookupCanceled(LookupEvent event) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.intellij.internal;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupItem;
|
||||
import com.intellij.codeInsight.lookup.LookupManager;
|
||||
import com.intellij.codeInsight.lookup.impl.LookupImpl;
|
||||
import com.intellij.codeInsight.completion.CompletionLookupArranger;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
@@ -33,7 +33,7 @@ public class DumpLookupElementWeights extends AnAction implements DumbAware {
|
||||
final int count = lookup.getPreferredItemsCount();
|
||||
for (int i = 0; i < model.getSize(); i++) {
|
||||
final LookupElement item = (LookupElement)model.getElementAt(i);
|
||||
System.out.println(item.getLookupString() + Arrays.toString(item.getUserData(LookupItem.WEIGHT)));
|
||||
System.out.println(item.getLookupString() + Arrays.toString(item.getUserData(CompletionLookupArranger.WEIGHT)));
|
||||
if (i == count - 1) {
|
||||
System.out.println("------------");
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ public class RenameDialog extends RefactoringDialog {
|
||||
final LookupElement[] lookupItems = items.toArray(new LookupElement[items.size()]);
|
||||
editor.getCaretModel().moveToOffset(prefix.length());
|
||||
editor.getSelectionModel().removeSelection();
|
||||
LookupManager.getInstance(myProject).showLookup(editor, lookupItems, prefix, null);
|
||||
LookupManager.getInstance(myProject).showLookup(editor, lookupItems, prefix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ public class TextFieldWithAutoCompletion extends EditorTextField {
|
||||
assert editor != null;
|
||||
|
||||
editor.getSelectionModel().removeSelection();
|
||||
LookupManager.getInstance(getProject()).showLookup(editor, calcLookupItems(getPrefix()), getPrefix(), null);
|
||||
LookupManager.getInstance(getProject()).showLookup(editor, calcLookupItems(getPrefix()), getPrefix());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -245,6 +245,7 @@
|
||||
<extensionPoint name="statistician" interface="com.intellij.psi.statistics.StatisticsExtensionPoint"/>
|
||||
<extensionPoint name="weigher" interface="com.intellij.psi.WeigherExtensionPoint"/>
|
||||
<extensionPoint name="completion.contributor" interface="com.intellij.codeInsight.completion.CompletionContributorEP"/>
|
||||
<extensionPoint name="completion.skip" interface="com.intellij.codeInsight.completion.CompletionPreselectSkipper"/>
|
||||
<extensionPoint name="lookup.charFilter" interface="com.intellij.codeInsight.lookup.CharFilter"/>
|
||||
<extensionPoint name="lookup.actionProvider" interface="com.intellij.codeInsight.lookup.LookupActionProvider"/>
|
||||
|
||||
|
||||
+2
-1
@@ -712,7 +712,8 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
|
||||
return myEmptyLookup ? LookupElement.EMPTY_ARRAY : null;
|
||||
}
|
||||
else {
|
||||
return lookup.getSortedItems();
|
||||
final List<LookupElement> list = lookup.getItems();
|
||||
return list.toArray(new LookupElement[list.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@ import com.intellij.codeInsight.lookup.LookupManager;
|
||||
import com.intellij.codeInsight.lookup.impl.TestLookupManager;
|
||||
import com.intellij.openapi.application.PluginPathManager;
|
||||
import com.intellij.testFramework.LightCodeInsightTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AntCompletionTest extends LightCodeInsightTestCase {
|
||||
|
||||
@@ -83,9 +86,6 @@ public class AntCompletionTest extends LightCodeInsightTestCase {
|
||||
public void testInsertion1() throws Exception {
|
||||
configureByFile("test8.xml");
|
||||
performNormalCompletion();
|
||||
if (getItems() != null) {
|
||||
select();
|
||||
}
|
||||
|
||||
checkResultByFile("/test8-out.xml");
|
||||
}
|
||||
@@ -93,18 +93,12 @@ public class AntCompletionTest extends LightCodeInsightTestCase {
|
||||
public void testInsertion2() throws Exception {
|
||||
configureByFile("test9.xml");
|
||||
performNormalCompletion();
|
||||
if (getItems() != null) {
|
||||
select();
|
||||
}
|
||||
checkResultByFile("/test8-out.xml");
|
||||
}
|
||||
|
||||
public void testTargetCompletion() throws Exception {
|
||||
configureByFile("targetCompletion.xml");
|
||||
performNormalCompletion();
|
||||
if (getItems() != null) {
|
||||
select();
|
||||
}
|
||||
checkResultByFile("/targetCompletion-out.xml");
|
||||
}
|
||||
|
||||
@@ -115,18 +109,13 @@ public class AntCompletionTest extends LightCodeInsightTestCase {
|
||||
AntSupport.markFileAsAntFile(myVFile, myFile.getViewProvider(), true);
|
||||
|
||||
performNormalCompletion();
|
||||
if (getItems() != null) {
|
||||
select();
|
||||
}
|
||||
select();
|
||||
checkResultByFile("/targetCompletion2-out.xml");
|
||||
}
|
||||
|
||||
public void testEntityCompletion() throws Exception {
|
||||
configureByFile("EntityCompletion.xml");
|
||||
performNormalCompletion();
|
||||
if (getItems() != null) {
|
||||
select();
|
||||
}
|
||||
|
||||
checkResultByFile("EntityCompletion-out.xml");
|
||||
}
|
||||
@@ -174,32 +163,32 @@ public class AntCompletionTest extends LightCodeInsightTestCase {
|
||||
checkResultByFile(testName + "-out.xml");
|
||||
}
|
||||
|
||||
private void select() {
|
||||
private static void select() {
|
||||
select(Lookup.NORMAL_SELECT_CHAR, getSelected());
|
||||
}
|
||||
|
||||
private void performNormalCompletion() {
|
||||
private static void performNormalCompletion() {
|
||||
new CodeCompletionHandlerBase(CompletionType.BASIC).invoke(getProject(), getEditor(), AntSupport.getAntFile(myFile));
|
||||
}
|
||||
|
||||
private void select(char completionChar, LookupElement item) {
|
||||
private static void select(char completionChar, LookupElement item) {
|
||||
((TestLookupManager)LookupManager.getInstance(getProject())).forceSelection(completionChar, item);
|
||||
}
|
||||
|
||||
private LookupElement getSelected() {
|
||||
return LookupManager.getInstance(getProject()).getActiveLookup().getCurrentItem();
|
||||
private static LookupElement getSelected() {
|
||||
final Lookup lookup = LookupManager.getInstance(getProject()).getActiveLookup();
|
||||
return lookup.getCurrentItem();
|
||||
}
|
||||
|
||||
private LookupElement[] getItems() {
|
||||
return ((TestLookupManager)LookupManager.getInstance(getProject())).getItems();
|
||||
@NotNull
|
||||
private static LookupElement[] getItems() {
|
||||
final List<LookupElement> list = LookupManager.getInstance(getProject()).getActiveLookup().getItems();
|
||||
return list.toArray(new LookupElement[list.size()]);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
if (getItems() != null) LookupManager.getInstance(getProject()).hideActiveLookup();
|
||||
LookupManager.getInstance(getProject()).hideActiveLookup();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
//public static void main(String[] args) {
|
||||
// new TestRunner().doRun(new TestSuite(AntCompletionTest.class));
|
||||
//}
|
||||
}
|
||||
|
||||
+2
-6
@@ -62,12 +62,8 @@ public final class CompleteWordFromDictionaryAction extends AnAction {
|
||||
lookupItems.add(LookupElementBuilder.create(variant));
|
||||
}
|
||||
|
||||
LookupElement[] items = new LookupElement[lookupItems.size()];
|
||||
items = lookupItems.toArray(items);
|
||||
LookupManager lookupManager = LookupManager.getInstance(project);
|
||||
lookupManager.showLookup(editor, items, prefix, null);
|
||||
|
||||
/*AnnotationHolder.createInfoAnnotation(TextRange.from(0, prefix.length()), "test");*/
|
||||
LookupElement[] items = lookupItems.toArray(new LookupElement[lookupItems.size()]);
|
||||
LookupManager.getInstance(project).showLookup(editor, items, prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class ChangeTo implements SpellCheckerQuickFix {
|
||||
LookupElement[] items = new LookupElement[lookupItems.size()];
|
||||
items = lookupItems.toArray(items);
|
||||
LookupManager lookupManager = LookupManager.getInstance(project);
|
||||
lookupManager.showLookup(editor, items, null);
|
||||
lookupManager.showLookup(editor, items);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -746,8 +746,8 @@
|
||||
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.PreferShorterWeigher" id="shorter"
|
||||
order="after fieldsAndGetters"/>
|
||||
|
||||
<weigher key="preferredCompletionItem" implementationClass="com.intellij.codeInsight.completion.SkipAbstractExpectedTypeWeigher"
|
||||
id="skipAbstract"/>
|
||||
<completion.skip implementation="com.intellij.codeInsight.completion.SkipAbstractExpectedTypeWeigher" id="skipAbstract"/>
|
||||
|
||||
|
||||
<extendWordSelectionHandler implementation="com.intellij.codeInsight.editorActions.wordSelection.LiteralSelectioner"/>
|
||||
<extendWordSelectionHandler implementation="com.intellij.codeInsight.editorActions.wordSelection.DocCommentSelectioner"/>
|
||||
|
||||
@@ -116,7 +116,7 @@ public class XmlTagRenameDialog extends RefactoringDialog {
|
||||
LookupElement[] lookupItems = set.toArray(new LookupElement[set.size()]);
|
||||
editor.getCaretModel().moveToOffset(prefix.length());
|
||||
editor.getSelectionModel().removeSelection();
|
||||
LookupManager.getInstance(getProject()).showLookup(editor, lookupItems, prefix, null);
|
||||
LookupManager.getInstance(getProject()).showLookup(editor, lookupItems, prefix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user