diff --git a/platform/core-impl/src/com/intellij/util/DocumentUtil.java b/platform/core-impl/src/com/intellij/util/DocumentUtil.java index d24da8a3caef..6eb84897d985 100644 --- a/platform/core-impl/src/com/intellij/util/DocumentUtil.java +++ b/platform/core-impl/src/com/intellij/util/DocumentUtil.java @@ -29,8 +29,15 @@ public class DocumentUtil { private DocumentUtil() { } - - // TODO den add doc + + /** + * Ensures that given task is executed when given document is at the given 'in bulk' mode. + * + * @param document target document + * @param executeInBulk true to force given document to be in bulk mode when given task is executed; + * false to force given document to be not in bulk mode when given task is executed + * @param task task to execute + */ public static void executeInBulk(@NotNull Document document, final boolean executeInBulk, @NotNull Runnable task) { if (!(document instanceof DocumentEx)) { task.run(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java index c59007aa2643..a419d07e811d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java @@ -28,6 +28,7 @@ import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; import com.intellij.openapi.editor.actionSystem.EditorActionManager; import com.intellij.openapi.editor.actionSystem.EditorTextInsertHandler; +import com.intellij.openapi.editor.ex.DocumentEx; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; @@ -39,6 +40,7 @@ import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.util.DocumentUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.Producer; import com.intellij.util.containers.HashMap; @@ -365,15 +367,23 @@ public class PasteHandler extends EditorActionHandler implements EditorTextInser } } - private static void reformatBlock(Project project, Editor editor, int startOffset, int endOffset) { + private static void reformatBlock(final Project project, final Editor editor, final int startOffset, final int endOffset) { PsiDocumentManager.getInstance(project).commitAllDocuments(); - PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + Runnable task = new Runnable() { + @Override + public void run() { + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + try { + CodeStyleManager.getInstance(project).reformatRange(file, startOffset, endOffset, true); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + }; - try { - CodeStyleManager.getInstance(project).reformatRange(file, startOffset, endOffset, true); - } - catch (IncorrectOperationException e) { - LOG.error(e); + if (endOffset - startOffset > 1000) { + DocumentUtil.executeInBulk(editor.getDocument(), true, task); } } diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java index 54a2ab6e1e14..6ef3916b343d 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java @@ -321,8 +321,9 @@ class FormatProcessor { * false otherwise */ @SuppressWarnings({"deprecation"}) - private boolean applyChangesAtBulkMode(final List blocksToModify, final FormattingModel model, - @NotNull CommonCodeStyleSettings.IndentOptions indentOption) + private boolean applyChangesAtRewriteMode(@NotNull final List blocksToModify, + @NotNull final FormattingModel model, + @NotNull CommonCodeStyleSettings.IndentOptions indentOption) { FormattingDocumentModel documentModel = model.getDocumentModel(); Document document = documentModel.getDocument(); @@ -366,14 +367,13 @@ class FormatProcessor { @Nullable private static DocumentEx getAffectedDocument(final FormattingModel model) { - if (model instanceof DocumentBasedFormattingModel) { - final Document document = ((DocumentBasedFormattingModel)model).getDocument(); - if (document instanceof DocumentEx) return (DocumentEx)document; - }/* else if (false) { // till issue with persistent range markers dropped fixed - Document document = model.getDocumentModel().getDocument(); - if (document instanceof DocumentEx) return (DocumentEx)document; - }*/ - return null; + final Document document = model.getDocumentModel().getDocument(); + if (document instanceof DocumentEx) { + return (DocumentEx)document; + } + else { + return null; + } } private static int replaceWhiteSpace(final FormattingModel model, @@ -1397,7 +1397,7 @@ class FormatProcessor { myResetBulkUpdateState = true; } if (blocksToModifyCount > BULK_REPLACE_OPTIMIZATION_CRITERIA - && applyChangesAtBulkMode(myBlocksToModify, myModel, myDefaultIndentOption)) + && applyChangesAtRewriteMode(myBlocksToModify, myModel, myDefaultIndentOption)) { setDone(true); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index f0b9fba78eef..fbed924fac7d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -715,6 +715,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi myMousePressedEvent = null; myMouseMovedEvent = null; Disposer.dispose(myCaretModel); + Disposer.dispose(mySoftWrapModel); clearCaretThread(); myFocusListeners.clear(); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java index 2dcdb0caf56e..8f8627072794 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java @@ -16,6 +16,7 @@ package com.intellij.openapi.editor.impl; import com.intellij.diagnostic.Dumpable; +import com.intellij.openapi.Disposable; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -52,7 +53,9 @@ import java.util.List; * @author Denis Zhdanov * @since Jun 8, 2010 12:47:32 PM */ -public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentListener, FoldingListener, PropertyChangeListener, Dumpable { +public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentListener, DocumentBulkUpdateListener, FoldingListener, + PropertyChangeListener, Dumpable, Disposable +{ /** * Holds name of JVM property which presence should trigger debug-aware soft wraps processing. @@ -109,6 +112,8 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi * Current field serves as a flag that indicates if all preliminary actions necessary for successful soft wraps processing is done. */ private boolean myUpdateInProgress; + + private boolean myBulkUpdateInProgress; /** * There is a possible case that target document is changed while its editor is inactive (e.g. user opens two editors for classes @@ -169,6 +174,8 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi myUseSoftWraps = settings.isUseSoftWraps(); editor.addPropertyChangeListener(this); + + ApplicationManager.getApplication().getMessageBus().connect(this).subscribe(DocumentBulkUpdateListener.TOPIC, this); } /** @@ -370,7 +377,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @NotNull @Override public LogicalPosition visualToLogicalPosition(@NotNull VisualPosition visual) { - if (myUpdateInProgress || !prepareToMapping()) { + if (myBulkUpdateInProgress || myUpdateInProgress || !prepareToMapping()) { return myEditor.visualToLogicalPosition(visual, false); } myActive++; @@ -386,7 +393,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @NotNull @Override public LogicalPosition offsetToLogicalPosition(int offset) { - if (myUpdateInProgress || !prepareToMapping()) { + if (myBulkUpdateInProgress || myUpdateInProgress || !prepareToMapping()) { return myEditor.offsetToLogicalPosition(offset, false); } myActive++; @@ -401,7 +408,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @NotNull public LogicalPosition adjustLogicalPosition(LogicalPosition defaultLogical, int offset) { - if (myUpdateInProgress || !prepareToMapping()) { + if (myBulkUpdateInProgress || myUpdateInProgress || !prepareToMapping()) { return defaultLogical; } @@ -418,7 +425,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @Override @NotNull public VisualPosition adjustVisualPosition(@NotNull LogicalPosition logical, @NotNull VisualPosition defaultVisual) { - if (myUpdateInProgress || !prepareToMapping()) { + if (myBulkUpdateInProgress || myUpdateInProgress || !prepareToMapping()) { return defaultVisual; } @@ -566,6 +573,9 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @Override public void beforeDocumentChange(DocumentEvent event) { + if (myBulkUpdateInProgress) { + return; + } myUpdateInProgress = true; if (!isSoftWrappingEnabled()) { myDirty = true; @@ -578,6 +588,9 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @Override public void documentChanged(DocumentEvent event) { + if (myBulkUpdateInProgress) { + return; + } myUpdateInProgress = false; if (!isSoftWrappingEnabled()) { return; @@ -587,6 +600,20 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi } } + @Override + public void updateStarted(@NotNull Document doc) { + myBulkUpdateInProgress = true; + } + + @Override + public void updateFinished(@NotNull Document doc) { + myBulkUpdateInProgress = false; + if (!isSoftWrappingEnabled()) { + return; + } + recalculate(); + } + @Override public void onFoldRegionStateChange(@NotNull FoldRegion region) { myUpdateInProgress = true; @@ -619,6 +646,11 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi return myDataMapper; } + @Override + public void dispose() { + release(); + } + @Override public void release() { myDataMapper.release(); @@ -632,6 +664,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi myApplianceManager.reset(); myDeferredFoldRegions.clear(); myEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER); + myApplianceManager.recalculateIfNecessary(); } public SoftWrapApplianceManager getApplianceManager() {