diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java index fcf92f5c8a61..9e56db996ef5 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -220,15 +220,14 @@ public class JavaCompletionContributor extends CompletionContributor { addKeywords(parameters, result); - addAllClasses(parameters, result, position, inheritors); + addAllClasses(parameters, result, inheritors); result.stopHere(); } public static void addAllClasses(CompletionParameters parameters, final CompletionResultSet result, - PsiElement position, final InheritorsHolder inheritors) { - if (shouldRunClassNameCompletion(result, position)) { + if (shouldRunClassNameCompletion(result, parameters)) { JavaClassNameCompletionContributor.addAllClasses(parameters, result, new Consumer() { @Override public void consume(LookupElement element) { @@ -314,7 +313,8 @@ public class JavaCompletionContributor extends CompletionContributor { } } - private static boolean shouldRunClassNameCompletion(CompletionResultSet result, PsiElement position) { + private static boolean shouldRunClassNameCompletion(CompletionResultSet result, CompletionParameters parameters) { + PsiElement position = parameters.getPosition(); final PsiElement parent = position.getParent(); if (!(parent instanceof PsiJavaCodeReferenceElement)) return false; if (((PsiJavaCodeReferenceElement)parent).getQualifier() != null) return false; @@ -331,7 +331,7 @@ public class JavaCompletionContributor extends CompletionContributor { return false; } - return StringUtil.isNotEmpty(result.getPrefixMatcher().getPrefix()); + return StringUtil.isCapitalized(result.getPrefixMatcher().getPrefix()) || parameters.getInvocationCount() >= 2 || parameters.relaxMatching(); } private static void completeAnnotationAttributeName(CompletionResultSet result, PsiElement insertedElement, diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java index aea4cc222e4c..abc1425bdac8 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java @@ -103,7 +103,7 @@ public class JavaDocCompletionContributor extends CompletionContributor { result.addElement(item); } - JavaCompletionContributor.addAllClasses(parameters, result, position, new InheritorsHolder(position, result)); + JavaCompletionContributor.addAllClasses(parameters, result, new InheritorsHolder(position, result)); } } }); diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java index c8d9ce3ae398..d82b19dd8c87 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java @@ -29,9 +29,10 @@ public class CompletionParameters { private final CompletionType myCompletionType; private final int myOffset; private final int myInvocationCount; + private final boolean myRelaxedMatching; protected CompletionParameters(@NotNull final PsiElement position, @NotNull final PsiFile originalFile, - final CompletionType completionType, int offset, final int invocationCount) { + final CompletionType completionType, int offset, final int invocationCount, final boolean relaxedMatching) { assert offset >= position.getTextRange().getStartOffset(); myPosition = position; assert position.isValid(); @@ -39,14 +40,19 @@ public class CompletionParameters { myCompletionType = completionType; myOffset = offset; myInvocationCount = invocationCount; + myRelaxedMatching = relaxedMatching; } public CompletionParameters withType(CompletionType type) { - return new CompletionParameters(myPosition, myOriginalFile, type, myOffset, myInvocationCount); + return new CompletionParameters(myPosition, myOriginalFile, type, myOffset, myInvocationCount, myRelaxedMatching); } public CompletionParameters withInvocationCount(int newCount) { - return new CompletionParameters(myPosition, myOriginalFile, myCompletionType, myOffset, newCount); + return new CompletionParameters(myPosition, myOriginalFile, myCompletionType, myOffset, newCount, myRelaxedMatching); + } + + public CompletionParameters withRelaxedMatching() { + return new CompletionParameters(myPosition, myOriginalFile, myCompletionType, myOffset, myInvocationCount, true); } @NotNull @@ -82,4 +88,8 @@ public class CompletionParameters { public int getInvocationCount() { return myInvocationCount; } + + public boolean relaxMatching() { + return myRelaxedMatching; + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index 421341b5e3cf..fa0de08f642f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -53,6 +53,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.NameUtil; import com.intellij.psi.impl.PsiFileEx; import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; @@ -291,11 +292,20 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { indicator.duringCompletion(initContext); ProgressManager.checkCanceled(); - data.set(CompletionService.getCompletionService().performCompletion(parameters, new Consumer() { + Consumer consumer = new Consumer() { public void consume(final LookupElement lookupElement) { indicator.addItem(lookupElement); } - })); + }; + LookupElement[] result = CompletionService.getCompletionService().performCompletion(parameters, consumer); + if (NameUtil.isUseMinusculeHumpMatcher() && parameters.getInvocationCount() == 0) { + if (result.length == 0) { + result = CompletionService.getCompletionService().performCompletion(parameters.withRelaxedMatching(), consumer); + } else { + indicator.restartOnEmpty = true; + } + } + data.set(result); } }); } @@ -347,7 +357,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { LOG.error("wrong text: copy='" + fileCopy.getText() + "'; element='" + insertedElement.getText() + "'; range=" + range); } - return new CompletionParameters(insertedElement, fileCopy.getOriginalFile(), myCompletionType, offset, invocationCount); + return new CompletionParameters(insertedElement, fileCopy.getOriginalFile(), myCompletionType, offset, invocationCount, false); } private AutoCompletionDecision shouldAutoComplete( diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index 5c51cacbda78..e77fad64b7cb 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.completion.impl.CompletionServiceImpl; +import com.intellij.codeInsight.editorActions.CompletionAutoPopupHandler; import com.intellij.codeInsight.hint.EditorHintListener; import com.intellij.codeInsight.hint.HintManager; import com.intellij.codeInsight.lookup.*; @@ -399,7 +400,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement Disposer.dispose(myQueue); CompletionProgressIndicator currentCompletion = CompletionServiceImpl.getCompletionService().getCurrentCompletion(); - assert currentCompletion == this : currentCompletion + "!=" + this; + LOG.assertTrue(currentCompletion == this, currentCompletion + "!=" + this); CompletionServiceImpl.getCompletionService().setCurrentCompletion(null); CompletionServiceImpl.assertPhase(CompletionPhase.BgCalculation.class, CompletionPhase.ItemsCalculated.class, CompletionPhase.Synchronous.class, CompletionPhase.Restarted.class); @@ -573,6 +574,8 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } } + public boolean restartOnEmpty = false; + public void prefixUpdated() { final CharSequence text = myEditor.getDocument().getCharsSequence(); final int caretOffset = myEditor.getCaretModel().getOffset(); @@ -585,7 +588,9 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } } - hideAutopopupIfMeaningless(); + if (hideAutopopupIfMeaningless() && restartOnEmpty) { + CompletionAutoPopupHandler.scheduleAutoPopup(getProject(), myEditor, getParameters().getOriginalFile()); + } updateFocus(); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CamelHumpMatcher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CamelHumpMatcher.java index 2e7378f5117d..661f47d6fb9c 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CamelHumpMatcher.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CamelHumpMatcher.java @@ -28,13 +28,15 @@ public class CamelHumpMatcher extends PrefixMatcher { private NameUtil.Matcher myMatcher; private final boolean myCaseSensitive; private final int currentSetting; + private final boolean myRelaxedMatching; public CamelHumpMatcher(@NotNull final String prefix) { - this(prefix, true); + this(prefix, true, false); } - public CamelHumpMatcher(String prefix, boolean caseSensitive) { + public CamelHumpMatcher(String prefix, boolean caseSensitive, boolean relaxedMatching) { super(prefix); + myRelaxedMatching = relaxedMatching; currentSetting = CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE; myCaseSensitive = caseSensitive; } @@ -47,7 +49,7 @@ public class CamelHumpMatcher extends PrefixMatcher { ourLastCompletionCaseSetting = currentSetting; } - NameUtil.Matcher pattern = ourPatternCache.get(myPrefix); + NameUtil.Matcher pattern = ourPatternCache.get(myRelaxedMatching + myPrefix); if (pattern == null) { pattern = createCamelHumpsMatcher(); ourPatternCache.put(myPrefix, pattern); @@ -81,7 +83,7 @@ public class CamelHumpMatcher extends PrefixMatcher { @NotNull public PrefixMatcher cloneWithPrefix(@NotNull final String prefix) { - return new CamelHumpMatcher(prefix); + return new CamelHumpMatcher(prefix, myCaseSensitive, myRelaxedMatching); } private NameUtil.Matcher createCamelHumpsMatcher() { @@ -89,6 +91,10 @@ public class CamelHumpMatcher extends PrefixMatcher { return NameUtil.buildCompletionMatcher(myPrefix, 0, true, true); } + if (myRelaxedMatching) { + return NameUtil.buildCompletionMatcher(myPrefix, 0, true, true); + } + switch (CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE) { case CodeInsightSettings.NONE: return NameUtil.buildCompletionMatcher(myPrefix, 0, true, true); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java index 99b2bf31a3c5..ec0b1ded9eb0 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java @@ -82,7 +82,7 @@ public class CompletionServiceImpl extends CompletionService{ final PsiElement position = parameters.getPosition(); final String prefix = CompletionData.findPrefixStatic(position, parameters.getOffset()); final String textBeforePosition = parameters.getPosition().getContainingFile().getText().substring(0, parameters.getOffset()); - return new CompletionResultSetImpl(consumer, textBeforePosition, new CamelHumpMatcher(prefix), contributor, defaultSorter(parameters), null); + return new CompletionResultSetImpl(consumer, textBeforePosition, new CamelHumpMatcher(prefix, true, parameters.relaxMatching()), contributor, defaultSorter(parameters), null); } @Override @@ -160,7 +160,7 @@ public class CompletionServiceImpl extends CompletionService{ @NotNull @Override public CompletionResultSet caseInsensitive() { - return withPrefixMatcher(new CamelHumpMatcher(getPrefixMatcher().getPrefix(), false)); + return withPrefixMatcher(new CamelHumpMatcher(getPrefixMatcher().getPrefix(), false, false)); } @Override diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java index caf48987b262..207642e11676 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java @@ -76,6 +76,11 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate { return Result.CONTINUE; } + scheduleAutoPopup(project, editor, file); + return Result.STOP; + } + + public static void scheduleAutoPopup(final Project project, final Editor editor, final PsiFile file) { final boolean isMainEditor = FileEditorManager.getInstance(project).getSelectedTextEditor() == editor; final CompletionPhase.AutoPopupAlarm phase = new CompletionPhase.AutoPopupAlarm(); @@ -95,7 +100,6 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate { } }; AutoPopupController.getInstance(project).invokeAutoPopupRunnable(request, CodeInsightSettings.getInstance().AUTO_LOOKUP_DELAY); - return Result.STOP; } public static void invokeAutoPopupCompletion(Project project, final Editor editor) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java index 0721d3e3b227..bbb668e431ff 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java @@ -453,7 +453,7 @@ public class GroovyCompletionContributor extends CompletionContributor { } }); - if (StringUtil.isNotEmpty(result.getPrefixMatcher().getPrefix())) { + if (StringUtil.isCapitalized(result.getPrefixMatcher().getPrefix()) || parameters.getInvocationCount() >= 2 || parameters.relaxMatching()) { addAllClasses(parameters, result, inheritors); } }