fixed completion disappear, clearer API

This commit is contained in:
Alexey Kudravtsev
2011-07-06 14:31:57 +04:00
parent 6d055866d5
commit 4e62926d4c
5 changed files with 64 additions and 39 deletions
@@ -103,7 +103,7 @@ abstract class CompletionAutoPopupTestCase extends LightCodeInsightFixtureTestCa
}
edt {
PsiDocumentManager manager = PsiDocumentManager.getInstance(getProject());
manager.performWhenAllDocumentsAreCommitted("wait for all comm", runnable);
manager.cancelAndRunWhenAllCommitted("wait for all comm", runnable);
}
while (!committed.get()) {
UIUtil.pump();
@@ -18,6 +18,7 @@ package com.intellij.psi;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -37,7 +38,7 @@ public abstract class PsiDocumentManager {
* @param action to run when all documents committed
* @return true if action was run immediately (i.e. all documents are already committed)
*/
public abstract boolean performWhenAllDocumentsAreCommitted(@NotNull Object key, @NotNull Runnable action);
public abstract boolean cancelAndRunWhenAllCommitted(@NonNls @NotNull Object key, @NotNull Runnable action);
/**
* Returns the document manager instance for the specified project.
@@ -708,7 +708,7 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx
runnable.run();
}
else {
PsiDocumentManager.getInstance(myProject).performWhenAllDocumentsAreCommitted("start daemon when all committed", runnable);
PsiDocumentManager.getInstance(myProject).cancelAndRunWhenAllCommitted("start daemon when all committed", runnable);
}
}
};
@@ -34,6 +34,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.PsiDocumentManagerImpl;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import org.jetbrains.annotations.NotNull;
@@ -127,15 +128,10 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
final int time,
final boolean hasModifiers,
final Condition<PsiFile> condition) {
//if (true) {
// new CodeCompletionHandlerBase(completionType, invokedExplicitly, autopopup)
// .invokeCompletion(project, editor, time, hasModifiers);
// return;
//}
final Document document = editor.getDocument();
final long beforeStamp = document.getModificationStamp();
final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
documentManager.performWhenAllDocumentsAreCommitted("start completion when all docs committed", new Runnable() {
documentManager.cancelAndRunWhenAllCommitted("start completion when all docs committed", new Runnable() {
@Override
public void run() {
long afterStamp = document.getModificationStamp();
@@ -182,23 +178,23 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
public static void runLaterWithCommitted(@NotNull final Project project, final Document document, final Runnable runnable) {
final long beforeStamp = document.getModificationStamp();
PsiDocumentManager.getInstance(project).performWhenAllDocumentsAreCommitted("run later when committed", new Runnable() {
@Override
public void run() {
// later because we may end up in write action here if there was a synchronous commit
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (beforeStamp != document.getModificationStamp()) {
// no luck, will try later
runLaterWithCommitted(project, document, runnable);
((PsiDocumentManagerImpl)PsiDocumentManager.getInstance(project)).performWhenAllCommitted(new Runnable() {
@Override
public void run() {
// later because we may end up in write action here if there was a synchronous commit
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (beforeStamp != document.getModificationStamp()) {
// no luck, will try later
runLaterWithCommitted(project, document, runnable);
}
else {
runnable.run();
}
}
else {
runnable.run();
}
}
}, project.getDisposed());
}
});
}, project.getDisposed());
}
});
}
}
@@ -38,10 +38,7 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectLocator;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.UserDataHolderEx;
import com.intellij.openapi.util.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl;
@@ -245,23 +242,54 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
}
private final Map<Object, Runnable> actionsWhenAllDocumentsAreCommitted = new LinkedHashMap<Object, Runnable>(); //accessed from EDT only
private static final Object PERFORM_ALWAYS_KEY = new Object();
// returns true if action has been run immediately
/** Schedules action to be executed when all documents are committed.
* @return true if action has been run immediately, or false if action was scheduled for execution later.
*/
public boolean performWhenAllCommitted(@NotNull final Runnable action) {
ApplicationManager.getApplication().assertIsDispatchThread();
if (myUncommittedDocuments.isEmpty()) {
action.run();
return true;
}
CompositeRunnable actions = (CompositeRunnable)actionsWhenAllDocumentsAreCommitted.get(PERFORM_ALWAYS_KEY);
if (actions == null) {
actions = new CompositeRunnable();
actionsWhenAllDocumentsAreCommitted.put(PERFORM_ALWAYS_KEY, actions);
}
actions.add(action);
return false;
}
private static class CompositeRunnable extends ArrayList<Runnable> implements Runnable {
@Override
public void run() {
for (Runnable runnable : this) {
runnable.run();
}
}
}
/**
* Cancel previously registered action and schedules (new) action to be executed when all documents are committed.
* @param key the (unique) name of the action. This action will overwrite any action which was registered under this key earlier.
* @return true if action has been run immediately, or false if action was scheduled for execution later.
*/
@Override
public boolean performWhenAllDocumentsAreCommitted(@NotNull Object key, @NotNull final Runnable action) {
public boolean cancelAndRunWhenAllCommitted(@NotNull Object key, @NotNull final Runnable action) {
ApplicationManager.getApplication().assertIsDispatchThread();
if (myProject.isDisposed()) {
action.run();
return true;
}
if (!myUncommittedDocuments.isEmpty()) {
actionsWhenAllDocumentsAreCommitted.put(key, action);
return false;
if (myUncommittedDocuments.isEmpty()) {
action.run();
assert actionsWhenAllDocumentsAreCommitted.isEmpty() : actionsWhenAllDocumentsAreCommitted;
return true;
}
action.run();
assert actionsWhenAllDocumentsAreCommitted.isEmpty() : actionsWhenAllDocumentsAreCommitted;
return true;
actionsWhenAllDocumentsAreCommitted.put(key, action);
return false;
}
public static void addRunOnCommit(@NotNull Document document, @NotNull Runnable action) {