IDEA-88106 Auto-completion works incorrectly when I make and then fix a mistake

This commit is contained in:
peter
2012-07-02 13:15:17 +02:00
parent 5cec1d3638
commit 5a5cb78e31
12 changed files with 61 additions and 29 deletions
@@ -1272,4 +1272,22 @@ class Foo {
myFixture.checkResult 'class Foo {{ boolean <caret> }}'
}
@Override
protected void tearDown() {
CodeInsightSettings.instance.COMPLETION_CASE_SENSITIVE = CodeInsightSettings.FIRST_LETTER
super.tearDown()
}
public void testBackspaceShouldShowPreviousVariants() {
CodeInsightSettings.instance.COMPLETION_CASE_SENSITIVE = CodeInsightSettings.NONE
myFixture.addClass("class OuterX { static class TrueLine {} }")
myFixture.configureByText 'a.java', 'class Foo{ void foo(int truex) { return tr<caret> }}'
type 'ue'
assert myFixture.lookupElementStrings == ['true', 'truex']
type 'l'
assert myFixture.lookupElementStrings == ['TrueLine']
type '\b'
assert myFixture.lookupElementStrings == ['true', 'truex']
}
}
@@ -63,7 +63,7 @@ public abstract class CompletionTestCase extends DaemonAnalyzerTestCase {
}
protected void complete(final int time) {
new CodeCompletionHandlerBase(myType).invokeCompletion(myProject, myEditor, time, false);
new CodeCompletionHandlerBase(myType).invokeCompletion(myProject, myEditor, time);
LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
myItems = lookup == null ? null : lookup.getItems().toArray(new LookupElement[lookup.getItems().size()]);
@@ -57,7 +57,7 @@ public abstract class LightCompletionTestCase extends LightCodeInsightTestCase {
}
protected void complete(final int time) {
new CodeCompletionHandlerBase(myType).invokeCompletion(getProject(), getEditor(), time, false);
new CodeCompletionHandlerBase(myType).invokeCompletion(getProject(), getEditor(), time);
LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
myItems = lookup == null ? null : lookup.getItems().toArray(LookupElement.EMPTY_ARRAY);
@@ -121,7 +121,7 @@ public class AutoPopupController implements Disposable {
PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument());
if (file != null && condition != null && !condition.value(file)) return;
CompletionAutoPopupHandler.invokeCompletion(CompletionType.BASIC, true, myProject, editor, 0);
CompletionAutoPopupHandler.invokeCompletion(CompletionType.BASIC, true, myProject, editor, 0, false);
}
});
}
@@ -100,14 +100,18 @@ public class CodeCompletionHandlerBase {
public final void invokeCompletion(final Project project, final Editor editor) {
try {
invokeCompletion(project, editor, 1, false);
invokeCompletion(project, editor, 1);
}
catch (IndexNotReadyException e) {
DumbService.getInstance(project).showDumbModeNotification("Code completion is not available here while indices are being built");
}
}
public final void invokeCompletion(@NotNull final Project project, @NotNull final Editor editor, int time, boolean hasModifiers) {
public final void invokeCompletion(@NotNull final Project project, @NotNull final Editor editor, int time) {
invokeCompletion(project, editor, time, false, false);
}
public final void invokeCompletion(@NotNull final Project project, @NotNull final Editor editor, int time, boolean hasModifiers, boolean restarted) {
final PsiFile psiFile = PsiUtilBase.getPsiFileInEditor(editor, project);
assert psiFile != null : "no PSI file: " + FileDocumentManager.getInstance().getFile(editor.getDocument());
@@ -210,22 +214,8 @@ public class CodeCompletionHandlerBase {
};
if (autopopup) {
CommandProcessor.getInstance().runUndoTransparentAction(initCmd);
int offset = editor.getCaretModel().getOffset();
int psiOffset = Math.max(0, offset - 1);
PsiElement elementAt = InjectedLanguageUtil.findInjectedElementNoCommit(psiFile, psiOffset);
if (elementAt == null) {
elementAt = psiFile.findElementAt(psiOffset);
}
if (elementAt == null) return;
Language language = PsiUtilBase.findLanguageFromElement(elementAt);
for (CompletionConfidence confidence : CompletionConfidenceEP.forLanguage(language)) {
final ThreeState result = confidence.shouldSkipAutopopup(elementAt, psiFile, offset);
if (result == ThreeState.YES) return;
if (result == ThreeState.NO) break;
if (!restarted && shouldSkipAutoPopup(editor, psiFile)) {
return;
}
} else {
CommandProcessor.getInstance().executeCommand(project, initCmd, null, null);
@@ -234,6 +224,30 @@ public class CodeCompletionHandlerBase {
insertDummyIdentifier(initializationContext[0], hasModifiers, time);
}
private static boolean shouldSkipAutoPopup(Editor editor, PsiFile psiFile) {
int offset = editor.getCaretModel().getOffset();
int psiOffset = Math.max(0, offset - 1);
PsiElement elementAt = InjectedLanguageUtil.findInjectedElementNoCommit(psiFile, psiOffset);
if (elementAt == null) {
elementAt = psiFile.findElementAt(psiOffset);
}
if (elementAt == null) return true;
Language language = PsiUtilBase.findLanguageFromElement(elementAt);
for (CompletionConfidence confidence : CompletionConfidenceEP.forLanguage(language)) {
final ThreeState result = confidence.shouldSkipAutopopup(elementAt, psiFile, offset);
if (result == ThreeState.YES) {
return true;
}
if (result == ThreeState.NO) {
return false;
}
}
return false;
}
@NotNull
private LookupImpl obtainLookup(Editor editor) {
LookupImpl existing = (LookupImpl)LookupManager.getActiveLookup(editor);
@@ -658,7 +658,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
if (phase.checkExpired()) return;
CompletionAutoPopupHandler.invokeCompletion(myParameters.getCompletionType(),
isAutopopupCompletion(), project, myEditor, myParameters.getInvocationCount());
isAutopopupCompletion(), project, myEditor, myParameters.getInvocationCount(), true);
}
});
}
@@ -47,7 +47,7 @@ public abstract class BaseCodeCompletionAction extends AnAction implements HintM
assert project != null;
assert editor != null;
InputEvent inputEvent = e.getInputEvent();
new CodeCompletionHandlerBase(type).invokeCompletion(project, editor, time, inputEvent != null && inputEvent.getModifiers() != 0);
new CodeCompletionHandlerBase(type).invokeCompletion(project, editor, time, inputEvent != null && inputEvent.getModifiers() != 0, false);
}
@Override
@@ -79,7 +79,7 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
public static void invokeCompletion(CompletionType completionType,
boolean autopopup,
Project project, Editor editor, int time) {
Project project, Editor editor, int time, boolean restart) {
if (editor.isDisposed()) return;
// retrieve the injected file from scratch since our typing might have destroyed the old one completely
@@ -94,7 +94,7 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
}
Editor newEditor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(topLevelEditor, topLevelFile);
try {
new CodeCompletionHandlerBase(completionType, false, autopopup, false).invokeCompletion(project, newEditor, time, false);
new CodeCompletionHandlerBase(completionType, false, autopopup, false).invokeCompletion(project, newEditor, time, false, restart);
}
catch (IndexNotReadyException ignored) {
}
@@ -27,6 +27,6 @@ public class ClassNameCompleteMacro extends BaseCompleteMacro {
}
protected void invokeCompletionHandler(Project project, Editor editor) {
new CodeCompletionHandlerBase(CompletionType.BASIC, false, false, true).invokeCompletion(project, editor, 2, false);
new CodeCompletionHandlerBase(CompletionType.BASIC, false, false, true).invokeCompletion(project, editor, 2);
}
}
@@ -29,6 +29,6 @@ public class CompleteMacro extends BaseCompleteMacro {
protected void invokeCompletionHandler(Project project, Editor editor) {
new CodeCompletionHandlerBase(CompletionType.BASIC, ApplicationManager.getApplication().isUnitTestMode(), false, true)
.invokeCompletion(project, editor, 1, false);
.invokeCompletion(project, editor, 1);
}
}
@@ -27,6 +27,6 @@ public class CompleteSmartMacro extends BaseCompleteMacro {
}
protected void invokeCompletionHandler(Project project, Editor editor) {
new CodeCompletionHandlerBase(CompletionType.SMART).invokeCompletion(project, editor, 1, false);
new CodeCompletionHandlerBase(CompletionType.SMART).invokeCompletion(project, editor, 1);
}
}
@@ -941,7 +941,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
}
};
Editor editor = getCompletionEditor();
handler.invokeCompletion(getProject(), editor, invocationCount, false);
handler.invokeCompletion(getProject(), editor, invocationCount);
PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); // to compare with file text
}
}, null, null);