diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleManager.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleManager.java index 4c0055ceb905..e79ff8eedfc3 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleManager.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleManager.java @@ -216,4 +216,20 @@ public abstract class CodeStyleManager { * the file is read-only). */ public abstract void reformatNewlyAddedElement(@NotNull final ASTNode block, @NotNull final ASTNode addedElement) throws IncorrectOperationException; + + /** + * Formatting may be executed sequentially, i.e. the whole (re)formatting task is split into a number of smaller sub-tasks + * that are executed sequentially. That is done primarily for ability to show progress dialog during formatting (formatting + * is always performed from EDT, hence, the GUI freezes if we perform formatting as a single big iteration). + *
+ * However, there are situation when we don't want to use such an approach - for example, IntelliJ IDEA sometimes inserts dummy + * text into file in order to calculate formatting-specific data and removes it after that. We don't want to allow Swing events + * dispatching during that in order to not show that dummy text to the end-user. + * + * It's possible to configure that (implementation details are insignificant here) and current method serves as a read-only + * facade for obtaining information if 'sequential' processing is allowed at the moment. + * + * @returntrue if 'sequential' formatting is allowed now; false otherwise
+ */
+ public abstract boolean isSequentialProcessingAllowed();
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatAndOptimizeImportsProcessor.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatAndOptimizeImportsProcessor.java
index 8d82a14c80be..f5ed69680a5f 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatAndOptimizeImportsProcessor.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatAndOptimizeImportsProcessor.java
@@ -21,6 +21,8 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.codeStyle.CodeStyleManager;
+import com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
@@ -71,7 +73,13 @@ public class ReformatAndOptimizeImportsProcessor extends AbstractLayoutCodeProce
return new Runnable() {
public void run() {
r1.run();
- r2.run();
+ CodeStyleManagerImpl.setSequentialProcessingAllowed(false);
+ try {
+ r2.run();
+ }
+ finally {
+ CodeStyleManagerImpl.setSequentialProcessingAllowed(true);
+ }
}
};
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java
index 4708ab4c5307..b765cb3f1a90 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java
@@ -36,6 +36,7 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.formatter.DocumentBasedFormattingModel;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
@@ -188,7 +189,9 @@ public class CodeFormatterFacade {
project, mySettings, file.getFileType(), file);
FormatterEx formatter = FormatterEx.getInstanceEx();
- formatter.setProgressIndicator(new FormattingProgressIndicatorImpl(project, file, document));
+ if (CodeStyleManager.getInstance(project).isSequentialProcessingAllowed()) {
+ formatter.setProgressIndicator(new FormattingProgressIndicatorImpl(project, file, document));
+ }
formatter.format(model, mySettings, mySettings.getIndentOptions(file.getFileType()), ranges);
for (FormatTextRanges.FormatTextRange range : textRanges) {
TextRange textRange = range.getTextRange();
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java
index a8ab933f8d24..a6049ecbb69b 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java
@@ -48,8 +48,20 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.concurrent.TimeUnit;
+
public class CodeStyleManagerImpl extends CodeStyleManager {
+
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl");
+ private static final ThreadLocal'true' argument is not mandatory for successful processing even
+ * if this method is called with 'false' argument before.
+ *
+ * @param allowed flag that defines if {@link #isSequentialProcessingAllowed() sequential processing} should be allowed
+ */
+ public static void setSequentialProcessingAllowed(boolean allowed) {
+ ProcessingUnderProgressInfo info = SEQUENTIAL_PROCESSING_ALLOWED.get();
+ if (allowed) {
+ info.decrement();
+ }
+ else {
+ info.increment();
+ }
+ }
+
+ private static class ProcessingUnderProgressInfo {
+
+ private static final long DURATION_TIME = TimeUnit.MILLISECONDS.convert(5, TimeUnit.SECONDS);
+
+ private int myCount;
+ private long myEndTime;
+
+ public void increment() {
+ if (myCount > 0 && System.currentTimeMillis() > myEndTime) {
+ myCount = 0;
+ }
+ myCount++;
+ myEndTime = System.currentTimeMillis() + DURATION_TIME;
+ }
+
+ public void decrement() {
+ if (myCount <= 0) {
+ return;
+ }
+ myCount--;
+ }
+
+ public boolean isAllowed() {
+ return myCount <= 0 || System.currentTimeMillis() >= myEndTime;
+ }
+ }
}