diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/CompletionAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/CompletionAutoPopupTest.groovy index ef38aa1c0eed..db772de05bcb 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/CompletionAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/CompletionAutoPopupTest.groovy @@ -125,4 +125,31 @@ class CompletionAutoPopupTest extends LightCodeInsightFixtureTestCase { assertNull LookupManager.getActiveLookup(myFixture.getEditor()) } + public void testGenerallyFocusLookupInJavaMethod() { + myFixture.configureByText("a.java", """ + class Foo { + String foo(String iterable) { + return it; + } + } + """) + type 'e' + final def lookup = LookupManager.getActiveLookup(myFixture.getEditor()) + assertNotNull lookup + assertTrue lookup.focused + } + + public void testNoLookupFocusInJavaVariable() { + myFixture.configureByText("a.java", """ + class Foo { + String foo(String st) { + } + } + """) + type 'r' + final def lookup = LookupManager.getActiveLookup(myFixture.getEditor()) + assertNotNull lookup + assertFalse lookup.focused + } + } diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/AlwaysFocusLookup.java b/platform/lang-api/src/com/intellij/codeInsight/completion/AlwaysFocusLookup.java new file mode 100644 index 000000000000..028cb9a5f8b0 --- /dev/null +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/AlwaysFocusLookup.java @@ -0,0 +1,28 @@ +/* + * Copyright 2000-2010 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 org.jetbrains.annotations.NotNull; + +/** + * @author peter + */ +public class AlwaysFocusLookup extends CompletionConfidence { + @Override + public Boolean shouldFocusLookup(@NotNull CompletionParameters parameters) { + return true; + } +} diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java index 81d5ca258810..0d651e3cb9a4 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java @@ -16,13 +16,15 @@ package com.intellij.codeInsight.completion; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author peter */ public abstract class CompletionConfidence { - public abstract boolean shouldFocusLookup(@NotNull CompletionParameters parameters); + @Nullable + public abstract Boolean shouldFocusLookup(@NotNull CompletionParameters parameters); } diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/UnfocusedNameIdentifier.java b/platform/lang-api/src/com/intellij/codeInsight/completion/UnfocusedNameIdentifier.java new file mode 100644 index 000000000000..52bd3634623e --- /dev/null +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/UnfocusedNameIdentifier.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2010 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.psi.PsiElement; +import com.intellij.psi.PsiNameIdentifierOwner; +import org.jetbrains.annotations.NotNull; + +/** + * @author peter + */ +public class UnfocusedNameIdentifier extends CompletionConfidence { + @Override + public Boolean shouldFocusLookup(@NotNull CompletionParameters parameters) { + final PsiElement position = parameters.getPosition(); + final PsiElement parent = position.getParent(); + if (parent instanceof PsiNameIdentifierOwner && ((PsiNameIdentifierOwner)parent).getNameIdentifier() == position) { + return false; + } + return null; + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java b/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java index fb99b7c71dc8..caf36d6f81b8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java @@ -95,7 +95,7 @@ public class AutoPopupController implements Disposable { if (!file.isValid()) return; if (condition != null && !condition.value(file)) return; - new CodeCompletionHandlerBase(CompletionType.BASIC, false, false).invoke(myProject, editor, file); + new CodeCompletionHandlerBase(CompletionType.BASIC, false, true).invoke(myProject, editor, file); } }; 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 33f755b318ec..c5401a1bcf57 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -78,16 +78,16 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.CodeCompletionHandlerBase"); private final CompletionType myCompletionType; final boolean invokedExplicitly; - private final boolean myFocusLookup; + final boolean autopopup; public CodeCompletionHandlerBase(final CompletionType completionType) { - this(completionType, true, true); + this(completionType, true, false); } - public CodeCompletionHandlerBase(CompletionType completionType, boolean invokedExplicitly, boolean focusLookup) { + public CodeCompletionHandlerBase(CompletionType completionType, boolean invokedExplicitly, boolean autopopup) { myCompletionType = completionType; this.invokedExplicitly = invokedExplicitly; - this.myFocusLookup = focusLookup; + this.autopopup = autopopup; } public final void invoke(final Project project, final Editor editor) { @@ -100,7 +100,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { } try { - invokeCompletion(project, editor, psiFile, myFocusLookup ? 1 : 0); + invokeCompletion(project, editor, psiFile, autopopup ? 0 : 1); } catch (IndexNotReadyException e) { DumbService.getInstance(project).showDumbModeNotification("Code completion is not available here while indices are being built"); @@ -173,7 +173,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { ApplicationManager.getApplication().runWriteAction(runnable); } }; - if (!myFocusLookup) { + if (autopopup) { CommandProcessor.getInstance().runUndoTransparentAction(initCmd); } else { CommandProcessor.getInstance().executeCommand(project, initCmd, null, null); @@ -188,14 +188,15 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { } private boolean shouldFocusLookup(CompletionParameters parameters) { - if (myFocusLookup) { + if (!autopopup) { return true; } final Language language = PsiUtilBase.getLanguageAtOffset(parameters.getPosition().getContainingFile(), parameters.getOffset()); for (CompletionConfidence confidence : CompletionConfidenceEP.forLanguage(language)) { - if (confidence.shouldFocusLookup(parameters)) { - return true; + final Boolean result = confidence.shouldFocusLookup(parameters); + if (result != null) { + return result; } } return false; @@ -206,7 +207,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { LookupImpl existing = (LookupImpl)LookupManager.getActiveLookup(editor); if (existing != null) { existing.markReused(); - if (myFocusLookup) { + if (!autopopup) { existing.setFocused(true); } return existing; 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 14187b270522..b73c34570571 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -539,7 +539,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement @Override public boolean isAutopopupCompletion() { - return !myLookup.isFocused(); + return myHandler.autopopup; } @NotNull @@ -575,7 +575,8 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement public void restartCompletion() { closeAndFinish(false); - final CodeCompletionHandlerBase newHandler = new CodeCompletionHandlerBase(myParameters.getCompletionType(), false, myLookup.isFocused()); + final CodeCompletionHandlerBase newHandler = new CodeCompletionHandlerBase(myParameters.getCompletionType(), false, + !isAutopopupCompletion()); final PsiFile psiFileInEditor = PsiUtilBase.getPsiFileInEditor(myEditor, getProject()); newHandler.invokeCompletion(getProject(), myEditor, psiFileInEditor, myParameters.getInvocationCount()); } 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 89357b16be3f..3be94618a300 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java @@ -99,7 +99,7 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate { if (editor.isDisposed() || isMainEditor && FileEditorManager.getInstance(project).getSelectedTextEditor() != editor) return; if (ApplicationManager.getApplication().isWriteAccessAllowed()) return; //it will fail anyway - new CodeCompletionHandlerBase(CompletionType.BASIC, false, false).invoke(project, editor); + new CodeCompletionHandlerBase(CompletionType.BASIC, false, true).invoke(project, editor); final AutoPopupState state = new AutoPopupState(project, editor); editor.putUserData(STATE_KEY, state); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/Lookup.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/Lookup.java index 196a794e4996..d5a59779f083 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/Lookup.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/Lookup.java @@ -59,4 +59,6 @@ public interface Lookup extends UserDataHolder{ boolean isCompletion(); java.util.List getItems(); + + boolean isFocused(); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 647d4e152de4..97fd8250657c 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -147,6 +147,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { myModel.setArranger(arranger); } + @Override public boolean isFocused() { return myFocused; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/macro/ClassNameCompleteMacro.java b/platform/lang-impl/src/com/intellij/codeInsight/template/macro/ClassNameCompleteMacro.java index e6953933964b..6bf991033955 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/macro/ClassNameCompleteMacro.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/macro/ClassNameCompleteMacro.java @@ -25,6 +25,6 @@ public class ClassNameCompleteMacro extends BaseCompleteMacro { } CodeInsightActionHandler getCompletionHandler() { - return new CodeCompletionHandlerBase(CompletionType.CLASS_NAME, false, true); + return new CodeCompletionHandlerBase(CompletionType.CLASS_NAME, false, false); } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/macro/CompleteMacro.java b/platform/lang-impl/src/com/intellij/codeInsight/template/macro/CompleteMacro.java index 47632afe7327..50dba61e1dba 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/macro/CompleteMacro.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/macro/CompleteMacro.java @@ -26,6 +26,6 @@ public class CompleteMacro extends BaseCompleteMacro { } CodeInsightActionHandler getCompletionHandler() { - return new CodeCompletionHandlerBase(CompletionType.BASIC, ApplicationManager.getApplication().isUnitTestMode(), true); + return new CodeCompletionHandlerBase(CompletionType.BASIC, ApplicationManager.getApplication().isUnitTestMode(), false); } } \ No newline at end of file diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index d1f4e38627f5..81763d494d09 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -231,6 +231,9 @@ + + +