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 8546122d1bfa..c0ea9377f0b4 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -18,10 +18,7 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.completion.impl.CompletionServiceImpl; import com.intellij.codeInsight.editorActions.CompletionAutoPopupHandler; -import com.intellij.codeInsight.lookup.LookupAdapter; -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupEvent; -import com.intellij.codeInsight.lookup.LookupManager; +import com.intellij.codeInsight.lookup.*; import com.intellij.codeInsight.lookup.impl.LookupImpl; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; @@ -91,6 +88,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement private LightweightHint myHint; private final Semaphore myFreezeSemaphore; private Boolean myToRestart; + private boolean myRestartScheduled; private boolean myModifiersReleased; @@ -273,9 +271,10 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } private boolean isOutdated() { - return myDisposed || - myEditor.isDisposed() || - !ApplicationManager.getApplication().isUnitTestMode() && myEditor.getComponent().getRootPane() == null; + if (!myDisposed) { + LOG.assertTrue(this == CompletionServiceImpl.getCompletionService().getCurrentCompletion()); + } + return myDisposed || myEditor.isDisposed() || getProject().isDisposed(); } private void trackModifiers() { @@ -430,11 +429,15 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } public void closeAndFinish(boolean hideLookup) { + LOG.assertTrue(this == CompletionServiceImpl.getCompletionService().getCurrentCompletion()); + if (myHint != null) { myHint.hide(); } - if (LookupManager.getActiveLookup(myEditor) == myLookup) { + Lookup lookup = LookupManager.getActiveLookup(myEditor); + if (lookup != null) { + LOG.assertTrue(lookup == myLookup); myLookup.removeLookupListener(myLookupListener); finishCompletionProcess(); @@ -485,15 +488,11 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement invokeLaterIfNotDispatch(new Runnable() { public void run() { if (isOutdated()) return; - if (isCanceled() && myToRestart != Boolean.TRUE) return; - - //what if a new completion was invoked by the user before this 'later'? - if (CompletionProgressIndicator.this != CompletionServiceImpl.getCompletionService().getCurrentCompletion()) return; + if (!isBackgrounded()) return; + if (isCanceled() && !myRestartScheduled) return; myLookup.setCalculating(false); - if (!isBackgrounded()) return; - if (hideAutopopupIfMeaningless()) { return; } @@ -651,17 +650,15 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } public void scheduleRestart() { + myRestartScheduled = true; + if (CompletionAutoPopupHandler.ourTestingAutopopup) { System.out.println("CompletionProgressIndicator.scheduleRestart"); } - ApplicationManager.getApplication().assertIsDispatchThread(); - final int offset = myEditor.getCaretModel().getOffset(); - final long stamp = myEditor.getDocument().getModificationStamp(); final Project project = getProject(); - final boolean wasDumb = DumbService.getInstance(project).isDumb(); ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { @@ -669,15 +666,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement System.out.println("later"); } - if (myEditor.isDisposed() || project.isDisposed()) { - return; - } - - if (!wasDumb && DumbService.getInstance(project).isDumb()) { - return; - } - - if (myEditor.getCaretModel().getOffset() != offset || myEditor.getDocument().getModificationStamp() != stamp) { + if (isOutdated()) { return; } @@ -685,10 +674,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement System.out.println("invoking"); } - - if (!isOutdated()) { - closeAndFinish(false); - } + closeAndFinish(false); final CodeCompletionHandlerBase newHandler = new CodeCompletionHandlerBase(myParameters.getCompletionType(), false, isAutopopupCompletion()); final PsiFile psiFileInEditor = PsiUtilBase.getPsiFileInEditor(myEditor, project); 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 42ef142195d2..fd8ecf13cd62 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 @@ -17,6 +17,7 @@ package com.intellij.codeInsight.completion.impl; import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.util.text.StringUtil; @@ -66,6 +67,7 @@ public class CompletionServiceImpl extends CompletionService{ } public void setCurrentCompletion(@Nullable final CompletionProgressIndicator indicator) { + ApplicationManager.getApplication().assertIsDispatchThread(); if (indicator != null) { final CompletionProgressIndicator oldCompletion = myCurrentCompletion; final Throwable oldTrace = myTrace; 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 9f6f2915e42a..e2c58419226b 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 @@ -931,7 +931,12 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { public void restorePrefix() { if (myInitialPrefix != null) { - myEditor.getDocument().replaceString(getLookupStart(), myEditor.getCaretModel().getOffset(), myInitialPrefix); + performGuardedChange(new Runnable() { + @Override + public void run() { + myEditor.getDocument().replaceString(getLookupStart(), myEditor.getCaretModel().getOffset(), myInitialPrefix); + } + }); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java index 183ec15e0819..588624db8824 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java @@ -31,6 +31,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.editor.event.EditorFactoryAdapter; import com.intellij.openapi.editor.event.EditorFactoryEvent; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; @@ -76,6 +77,18 @@ public class LookupManagerImpl extends LookupManager { } }); + bus.connect().subscribe(DumbService.DUMB_MODE, new DumbService.DumbModeListener() { + @Override + public void enteredDumbMode() { + hideActiveLookup(); + } + + @Override + public void exitDumbMode() { + hideActiveLookup(); + } + }); + final EditorFactoryAdapter myEditorFactoryListener = new EditorFactoryAdapter() { public void editorReleased(EditorFactoryEvent event) {