mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
no more prefixMatcher in lookupElement
This commit is contained in:
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.completion.PrefixMatcher;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -61,7 +62,9 @@ public interface Lookup {
|
||||
|
||||
boolean isFocused();
|
||||
|
||||
@NotNull
|
||||
String itemPattern(LookupElement element);
|
||||
|
||||
@NotNull
|
||||
PrefixMatcher itemMatcher(LookupElement item);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.intellij.codeInsight.lookup;
|
||||
|
||||
import com.intellij.codeInsight.completion.InsertionContext;
|
||||
import com.intellij.codeInsight.completion.PrefixMatcher;
|
||||
import com.intellij.openapi.util.ClassConditionKey;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -35,7 +34,6 @@ import java.util.Set;
|
||||
*/
|
||||
public abstract class LookupElement extends UserDataHolderBase {
|
||||
public static final LookupElement[] EMPTY_ARRAY = new LookupElement[0];
|
||||
private PrefixMatcher myPrefixMatcher = PrefixMatcher.FALSE_MATCHER;
|
||||
|
||||
@NotNull
|
||||
public abstract String getLookupString();
|
||||
@@ -44,16 +42,6 @@ public abstract class LookupElement extends UserDataHolderBase {
|
||||
return Collections.singleton(getLookupString());
|
||||
}
|
||||
|
||||
public boolean setPrefixMatcher(@NotNull final PrefixMatcher matcher) {
|
||||
myPrefixMatcher = matcher;
|
||||
return myPrefixMatcher.prefixMatches(this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final PrefixMatcher getPrefixMatcher() {
|
||||
return myPrefixMatcher;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Object getObject() {
|
||||
return this;
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.intellij.codeInsight.lookup;
|
||||
|
||||
import com.intellij.codeInsight.completion.InsertHandler;
|
||||
import com.intellij.codeInsight.completion.InsertionContext;
|
||||
import com.intellij.codeInsight.completion.PrefixMatcher;
|
||||
import com.intellij.openapi.util.ClassConditionKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -32,23 +31,12 @@ public abstract class LookupElementDecorator<T extends LookupElement> extends Lo
|
||||
protected LookupElementDecorator(T delegate) {
|
||||
myDelegate = delegate;
|
||||
myDelegate.copyUserDataTo(this);
|
||||
final PrefixMatcher matcher = delegate.getPrefixMatcher();
|
||||
if (matcher != PrefixMatcher.FALSE_MATCHER) {
|
||||
assert matcher.prefixMatches(this);
|
||||
setPrefixMatcher(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
public T getDelegate() {
|
||||
return myDelegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setPrefixMatcher(@NotNull PrefixMatcher matcher) {
|
||||
myDelegate.setPrefixMatcher(matcher);
|
||||
return super.setPrefixMatcher(matcher);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getLookupString() {
|
||||
return myDelegate.getLookupString();
|
||||
|
||||
+9
-42
@@ -29,11 +29,9 @@ import com.intellij.injected.editor.EditorWindow;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.application.ex.ApplicationEx;
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -49,7 +47,6 @@ import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
@@ -67,7 +64,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@@ -291,12 +287,16 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
|
||||
indicator.duringCompletion(initContext);
|
||||
ProgressManager.checkCanceled();
|
||||
|
||||
final List<LookupElement> items = new ArrayList<LookupElement>();
|
||||
Consumer<LookupElement> consumer = new Consumer<LookupElement>() {
|
||||
public void consume(final LookupElement lookupElement) {
|
||||
indicator.addItem((MatchedLookupElement)lookupElement);
|
||||
MatchedLookupElement matched = (MatchedLookupElement)lookupElement;
|
||||
indicator.addItem(matched);
|
||||
items.add(matched.getDelegate());
|
||||
}
|
||||
};
|
||||
data.set(CompletionService.getCompletionService().performCompletion(parameters, consumer));
|
||||
CompletionService.getCompletionService().performCompletion(parameters, consumer);
|
||||
data.set(items.toArray(new LookupElement[items.size()]));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -423,12 +423,10 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
|
||||
}
|
||||
}
|
||||
else if (decision instanceof AutoCompletionDecision.InsertItem) {
|
||||
final LookupElement item = ((AutoCompletionDecision.InsertItem)decision).getElement();
|
||||
indicator.closeAndFinish(true);
|
||||
final Runnable restorePrefix = rememberDocumentState(indicator.getEditor());
|
||||
indicator.getOffsetMap()
|
||||
.addOffset(CompletionInitializationContext.START_OFFSET, (offset1 - indicator.getLookup().itemPattern(item).length()));
|
||||
handleSingleItem(offset2, indicator, items, item.getLookupString(), item);
|
||||
|
||||
final LookupElement item = ((AutoCompletionDecision.InsertItem)decision).getElement();
|
||||
indicator.getLookup().finishLookup(Lookup.AUTO_INSERT_SELECT_CHAR, item);
|
||||
|
||||
// the insert handler may have started a live template with completion
|
||||
if (CompletionService.getCompletionService().getCurrentCompletion() == null &&
|
||||
@@ -438,37 +436,6 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
protected static void handleSingleItem(final int offset2, final CompletionProgressIndicator context, final LookupElement[] items, final String _uniqueText, final LookupElement item) {
|
||||
new WriteCommandAction(context.getProject()) {
|
||||
protected void run(Result result) throws Throwable {
|
||||
String uniqueText = _uniqueText;
|
||||
|
||||
if (item.getObject() instanceof DeferredUserLookupValue && item.as(LookupItem.CLASS_CONDITION_KEY) != null) {
|
||||
if (!((DeferredUserLookupValue)item.getObject()).handleUserSelection(item.as(LookupItem.CLASS_CONDITION_KEY), context.getProject())) {
|
||||
return;
|
||||
}
|
||||
|
||||
uniqueText = item.getLookupString(); // text may be not ready yet
|
||||
}
|
||||
|
||||
if (!StringUtil.startsWithIgnoreCase(uniqueText, context.getLookup().itemPattern(item))) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EDITING_COMPLETION_CAMEL_HUMPS);
|
||||
}
|
||||
|
||||
insertLookupString(offset2, uniqueText, context.getEditor(), context.getOffsetMap());
|
||||
context.getEditor().getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
|
||||
lookupItemSelected(context, item, Lookup.AUTO_INSERT_SELECT_CHAR, Arrays.asList(items));
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
private static void insertLookupString(final int currentOffset, final String newText, final Editor editor, final OffsetMap offsetMap) {
|
||||
editor.getDocument().replaceString(offsetMap.getOffset(CompletionInitializationContext.START_OFFSET), currentOffset, newText);
|
||||
editor.getCaretModel().moveToOffset(offsetMap.getOffset(CompletionInitializationContext.START_OFFSET) + newText.length());
|
||||
editor.getSelectionModel().removeSelection();
|
||||
}
|
||||
|
||||
protected static void selectLookupItem(final LookupElement item, final char completionChar, final CompletionProgressIndicator context, final List<LookupElement> items) {
|
||||
final int caretOffset = context.getEditor().getCaretModel().getOffset();
|
||||
|
||||
|
||||
+2
-3
@@ -370,9 +370,8 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
|
||||
LOG.assertTrue(myParameters.getPosition().isValid());
|
||||
|
||||
LookupElement delegate = item.getDelegate();
|
||||
myItemSorters.put(delegate, item.getSorter());
|
||||
myLookup.addItem(delegate);
|
||||
myItemSorters.put(item.getDelegate(), item.getSorter());
|
||||
myLookup.addItem(item.getDelegate(), item.getPrefixMatcher());
|
||||
myCount++;
|
||||
if (unitTestMode) return;
|
||||
|
||||
|
||||
+2
-2
@@ -46,7 +46,7 @@ public class RelaxedMatchingContributor extends CompletionContributor {
|
||||
if (!elements.isEmpty() && parameters.getInvocationCount() == 0) {
|
||||
Set<String> prefixes = new HashSet<String>();
|
||||
for (MatchedLookupElement element : elements) {
|
||||
prefixes.add(element.getMatcher().getPrefix());
|
||||
prefixes.add(element.getPrefixMatcher().getPrefix());
|
||||
}
|
||||
for (String prefix : prefixes) {
|
||||
result.withPrefixMatcher(prefix)
|
||||
@@ -54,7 +54,7 @@ public class RelaxedMatchingContributor extends CompletionContributor {
|
||||
@Override
|
||||
public boolean accepts(@NotNull String s, ProcessingContext context) {
|
||||
for (MatchedLookupElement element : elements) {
|
||||
if (element.getMatcher().cloneWithPrefix(s).prefixMatches(element)) {
|
||||
if (element.getPrefixMatcher().cloneWithPrefix(s).prefixMatches(element)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -142,13 +142,12 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
|
||||
MatchedLookupElement matched = element.as(MatchedLookupElement.CLASS_CONDITION_KEY);
|
||||
if (matched != null) {
|
||||
getConsumer().consume(new MatchedLookupElement(element, matched.getMatcher(), matched.getSorter()));
|
||||
getConsumer().consume(new MatchedLookupElement(element, matched.getPrefixMatcher(), matched.getSorter()));
|
||||
return;
|
||||
}
|
||||
|
||||
PrefixMatcher matcher = getPrefixMatcher();
|
||||
if (matcher.prefixMatches(element)) {
|
||||
element.setPrefixMatcher(matcher);
|
||||
getConsumer().consume(new MatchedLookupElement(element, matcher, mySorter));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-52
@@ -15,15 +15,10 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.completion.impl;
|
||||
|
||||
import com.intellij.codeInsight.completion.InsertionContext;
|
||||
import com.intellij.codeInsight.completion.PrefixMatcher;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementDecorator;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.util.ClassConditionKey;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -39,7 +34,7 @@ public class MatchedLookupElement extends LookupElementDecorator<LookupElement>
|
||||
mySorter = sorter;
|
||||
}
|
||||
|
||||
public PrefixMatcher getMatcher() {
|
||||
public PrefixMatcher getPrefixMatcher() {
|
||||
return myMatcher;
|
||||
}
|
||||
|
||||
@@ -47,50 +42,4 @@ public class MatchedLookupElement extends LookupElementDecorator<LookupElement>
|
||||
return mySorter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleInsert(InsertionContext context) {
|
||||
if (!isCaseSensitive()) {
|
||||
if (!myMatcher.prefixMatches(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String prefix = myMatcher.getPrefix();
|
||||
final String oldLookupString = getLookupString();
|
||||
if (StringUtil.startsWithIgnoreCase(oldLookupString, prefix)) {
|
||||
final String newLookupString = handleCaseInsensitiveVariant(prefix, oldLookupString);
|
||||
if (!newLookupString.equals(oldLookupString)) {
|
||||
final Document document = context.getEditor().getDocument();
|
||||
int startOffset = context.getStartOffset();
|
||||
int tailOffset = context.getTailOffset();
|
||||
|
||||
assert startOffset >= 0 : "stale startOffset";
|
||||
assert tailOffset >= 0 : "stale tailOffset";
|
||||
|
||||
document.replaceString(startOffset, tailOffset, newLookupString);
|
||||
PsiDocumentManager.getInstance(context.getProject()).commitDocument(document);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
super.handleInsert(context);
|
||||
}
|
||||
|
||||
private static String handleCaseInsensitiveVariant(final String prefix, @NotNull final String lookupString) {
|
||||
final int length = prefix.length();
|
||||
if (length == 0) return lookupString;
|
||||
boolean isAllLower = true;
|
||||
boolean isAllUpper = true;
|
||||
boolean sameCase = true;
|
||||
for (int i = 0; i < length && (isAllLower || isAllUpper || sameCase); i++) {
|
||||
final char c = prefix.charAt(i);
|
||||
isAllLower = isAllLower && Character.isLowerCase(c);
|
||||
isAllUpper = isAllUpper && Character.isUpperCase(c);
|
||||
sameCase = sameCase && Character.isLowerCase(c) == Character.isLowerCase(lookupString.charAt(i));
|
||||
}
|
||||
if (sameCase) return lookupString;
|
||||
if (isAllLower) return lookupString.toLowerCase();
|
||||
if (isAllUpper) return lookupString.toUpperCase();
|
||||
return lookupString;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.intellij.codeInsight.lookup.impl;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.codeInsight.completion.CodeCompletionFeatures;
|
||||
import com.intellij.codeInsight.completion.CompletionLookupArranger;
|
||||
import com.intellij.codeInsight.completion.PrefixMatcher;
|
||||
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
|
||||
@@ -40,6 +41,7 @@ import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
@@ -76,6 +78,7 @@ import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class LookupImpl extends LightweightHint implements LookupEx, Disposable {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.lookup.impl.LookupImpl");
|
||||
@@ -120,6 +123,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
private boolean myReused;
|
||||
private boolean myChangeGuard;
|
||||
private LookupModel myModel = new LookupModel();
|
||||
private final Map<LookupElement, PrefixMatcher> myMatchers = new ConcurrentHashMap<LookupElement, PrefixMatcher>();
|
||||
private LookupHint myElementHint = null;
|
||||
private Alarm myHintAlarm = new Alarm();
|
||||
private JLabel mySortingLabel;
|
||||
@@ -253,14 +257,15 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
final List<LookupElement> items = myModel.getItems();
|
||||
myModel.clearItems();
|
||||
for (final LookupElement item : items) {
|
||||
addItem(item);
|
||||
addItem(item, itemMatcher(item));
|
||||
}
|
||||
checkReused();
|
||||
updateList();
|
||||
ensureSelectionVisible();
|
||||
}
|
||||
|
||||
public void addItem(LookupElement item) {
|
||||
public void addItem(LookupElement item, PrefixMatcher matcher) {
|
||||
myMatchers.put(item, matcher);
|
||||
myModel.addItem(item);
|
||||
|
||||
updateLookupWidth(item);
|
||||
@@ -495,7 +500,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
|
||||
private void addEmptyItem(DefaultListModel model) {
|
||||
LookupItem<String> item = new EmptyLookupItem(myCalculating ? " " : LangBundle.message("completion.no.suggestions"));
|
||||
item.setPrefixMatcher(new CamelHumpMatcher(""));
|
||||
myMatchers.put(item, new CamelHumpMatcher(""));
|
||||
if (!myCalculating) {
|
||||
myList.setFixedCellWidth(Math.max(myCellRenderer.updateMaximumWidth(renderItemApproximately(item)), myLookupTextWidth));
|
||||
}
|
||||
@@ -560,6 +565,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
return ContainerUtil.flatten(classifier.classify(better));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String itemPattern(LookupElement element) {
|
||||
return itemMatcher(element).getPrefix() + myAdditionalPrefix;
|
||||
@@ -587,8 +593,13 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PrefixMatcher itemMatcher(LookupElement item) {
|
||||
return item.getPrefixMatcher();
|
||||
PrefixMatcher matcher = myMatchers.get(item);
|
||||
if (matcher == null) {
|
||||
throw new AssertionError("Item not in lookup: item=" + item + "; lookup items=" + getItems());
|
||||
}
|
||||
return matcher;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -645,7 +656,10 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
}
|
||||
|
||||
public void finishLookup(final char completionChar) {
|
||||
final LookupElement item = (LookupElement)myList.getSelectedValue();
|
||||
finishLookup(completionChar, (LookupElement)myList.getSelectedValue());
|
||||
}
|
||||
|
||||
public void finishLookup(char completionChar, @Nullable final LookupElement item) {
|
||||
doHide(false, true);
|
||||
if (item == null ||
|
||||
item instanceof EmptyLookupItem ||
|
||||
@@ -662,30 +676,63 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
return;
|
||||
}
|
||||
|
||||
final String prefix = itemPattern(item);
|
||||
boolean plainMatch = ContainerUtil.or(item.getAllLookupStrings(), new Condition<String>() {
|
||||
@Override
|
||||
public boolean value(String s) {
|
||||
return StringUtil.startsWithIgnoreCase(s, prefix);
|
||||
}
|
||||
});
|
||||
if (!plainMatch) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EDITING_COMPLETION_CAMEL_HUMPS);
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
EditorModificationUtil.deleteSelectedText(myEditor);
|
||||
final int caretOffset = myEditor.getCaretModel().getOffset();
|
||||
final String prefix = itemPattern(item);
|
||||
int lookupStart = caretOffset - prefix.length();
|
||||
|
||||
final String lookupString = item.getLookupString();
|
||||
if (!lookupString.startsWith(prefix)) { //todo another lookup string may match the prefix
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.camelHumps");
|
||||
}
|
||||
|
||||
myEditor.getDocument().replaceString(lookupStart, caretOffset, lookupString);
|
||||
|
||||
int offset = lookupStart + lookupString.length();
|
||||
myEditor.getCaretModel().moveToOffset(offset);
|
||||
myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
myEditor.getSelectionModel().removeSelection();
|
||||
insertLookupString(item, prefix);
|
||||
}
|
||||
});
|
||||
|
||||
fireItemSelected(item, completionChar);
|
||||
}
|
||||
|
||||
private void insertLookupString(LookupElement item, final String prefix) {
|
||||
PrefixMatcher matcher = itemMatcher(item);
|
||||
|
||||
String lookupString = item.getLookupString();
|
||||
if (!item.isCaseSensitive() && matcher.prefixMatches(item) && StringUtil.startsWithIgnoreCase(lookupString, prefix)) {
|
||||
lookupString = handleCaseInsensitiveVariant(prefix, lookupString);
|
||||
}
|
||||
|
||||
EditorModificationUtil.deleteSelectedText(myEditor);
|
||||
final int caretOffset = myEditor.getCaretModel().getOffset();
|
||||
int lookupStart = caretOffset - prefix.length();
|
||||
myEditor.getDocument().replaceString(lookupStart, caretOffset, lookupString);
|
||||
|
||||
int offset = lookupStart + lookupString.length();
|
||||
myEditor.getCaretModel().moveToOffset(offset);
|
||||
myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
myEditor.getSelectionModel().removeSelection();
|
||||
}
|
||||
|
||||
private static String handleCaseInsensitiveVariant(final String prefix, @NotNull final String lookupString) {
|
||||
final int length = prefix.length();
|
||||
if (length == 0) return lookupString;
|
||||
boolean isAllLower = true;
|
||||
boolean isAllUpper = true;
|
||||
boolean sameCase = true;
|
||||
for (int i = 0; i < length && (isAllLower || isAllUpper || sameCase); i++) {
|
||||
final char c = prefix.charAt(i);
|
||||
isAllLower = isAllLower && Character.isLowerCase(c);
|
||||
isAllUpper = isAllUpper && Character.isUpperCase(c);
|
||||
sameCase = sameCase && Character.isLowerCase(c) == Character.isLowerCase(lookupString.charAt(i));
|
||||
}
|
||||
if (sameCase) return lookupString;
|
||||
if (isAllLower) return lookupString.toLowerCase();
|
||||
if (isAllUpper) return lookupString.toUpperCase();
|
||||
return lookupString;
|
||||
}
|
||||
|
||||
public int getLookupStart() {
|
||||
LOG.assertTrue(myLookupStartMarker.isValid());
|
||||
return myLookupStartMarker.getStartOffset();
|
||||
@@ -900,7 +947,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
return itmBounds;
|
||||
}
|
||||
|
||||
public void fireItemSelected(final LookupElement item, char completionChar){
|
||||
public void fireItemSelected(@Nullable final LookupElement item, char completionChar){
|
||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
||||
|
||||
if (item != null) {
|
||||
@@ -1039,7 +1086,11 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
myEditor.getDocument().insertString(offset, afterCaret);
|
||||
|
||||
final String newPrefix = presentPrefix + afterCaret;
|
||||
myModel.retainMatchingItems(newPrefix, this);
|
||||
|
||||
Map<LookupElement, PrefixMatcher> newItems = myModel.retainMatchingItems(newPrefix, this);
|
||||
myMatchers.clear();
|
||||
myMatchers.putAll(newItems);
|
||||
|
||||
myAdditionalPrefix = "";
|
||||
|
||||
offset += afterCaret.length();
|
||||
|
||||
@@ -200,12 +200,10 @@ public class LookupManagerImpl extends LookupManager {
|
||||
}
|
||||
});
|
||||
|
||||
CamelHumpMatcher matcher = new CamelHumpMatcher(prefix == null ? "" : prefix);
|
||||
if (items.length > 0) {
|
||||
for (final LookupElement item : items) {
|
||||
if (prefix != null) {
|
||||
item.setPrefixMatcher(new CamelHumpMatcher(prefix));
|
||||
}
|
||||
myActiveLookup.addItem(item);
|
||||
myActiveLookup.addItem(item, matcher);
|
||||
}
|
||||
myActiveLookup.refreshUi();
|
||||
} else {
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.lookup.impl;
|
||||
|
||||
import com.intellij.codeInsight.completion.PrefixMatcher;
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.SortedList;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -111,23 +111,27 @@ public class LookupModel {
|
||||
}
|
||||
}
|
||||
|
||||
void retainMatchingItems(final String newPrefix, final LookupImpl lookup) {
|
||||
@Nullable
|
||||
Map<LookupElement, PrefixMatcher> retainMatchingItems(final String newPrefix, final LookupImpl lookup) {
|
||||
synchronized (lock) {
|
||||
final List<LookupElement> newItems = ContainerUtil.findAll(myItems, new Condition<LookupElement>() {
|
||||
@Override
|
||||
public boolean value(LookupElement item) {
|
||||
return item.isValid() && item.setPrefixMatcher(lookup.itemMatcher(item).cloneWithPrefix(newPrefix));
|
||||
LinkedHashMap<LookupElement, PrefixMatcher> map = new LinkedHashMap<LookupElement, PrefixMatcher>();
|
||||
for (LookupElement item : myItems) {
|
||||
if (item.isValid()) {
|
||||
PrefixMatcher matcher = lookup.itemMatcher(item).cloneWithPrefix(newPrefix);
|
||||
if (matcher.prefixMatches(item)) {
|
||||
map.put(item, matcher);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (newItems.size() == myItems.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearItems();
|
||||
for (LookupElement newItem : newItems) {
|
||||
addItem(newItem);
|
||||
if (map.size() != myItems.size()) {
|
||||
clearItems();
|
||||
for (LookupElement newItem : map.keySet()) {
|
||||
addItem(newItem);
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-8
@@ -89,17 +89,12 @@ public class ListTemplatesHandler implements CodeInsightActionHandler {
|
||||
}
|
||||
|
||||
public static void showTemplatesLookup(final Project project, final Editor editor, Map<TemplateImpl, String> template2Argument) {
|
||||
ArrayList<LookupItem> array = new ArrayList<LookupItem>();
|
||||
final LookupImpl lookup = (LookupImpl)LookupManager.getInstance(project).createLookup(editor, LookupElement.EMPTY_ARRAY, null, LookupArranger.DEFAULT);
|
||||
for (TemplateImpl template : template2Argument.keySet()) {
|
||||
String argument = template2Argument.get(template);
|
||||
String prefix = computePrefix(template, argument);
|
||||
LookupItem item = new LookupItem(template, prefix);
|
||||
item.setPrefixMatcher(new CamelHumpMatcher(prefix));
|
||||
array.add(item);
|
||||
String prefix = computePrefix(template, template2Argument.get(template));
|
||||
lookup.addItem(new LookupItem(template, prefix), new CamelHumpMatcher(prefix));
|
||||
}
|
||||
LookupElement[] items = array.toArray(new LookupElement[array.size()]);
|
||||
|
||||
final LookupImpl lookup = (LookupImpl)LookupManager.getInstance(project).createLookup(editor, items, null, LookupArranger.DEFAULT);
|
||||
lookup.addLookupListener(new MyLookupAdapter(project, editor, template2Argument));
|
||||
lookup.show();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user