diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorDocumentPriorities.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorDocumentPriorities.java index 79cf1924369c..991248350268 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorDocumentPriorities.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorDocumentPriorities.java @@ -32,8 +32,8 @@ public class EditorDocumentPriorities { */ public static final int RANGE_MARKER = 40; - public static final int SOFT_WRAP_MODEL = 60; - public static final int FOLD_MODEL = 80; + public static final int FOLD_MODEL = 60; + public static final int SOFT_WRAP_MODEL = 80; public static final int LEXER_EDITOR = 100; public static final int CARET_MODEL = 120; public static final int SELECTION_MODEL = 140; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java index e2921401f901..f46d773a9f57 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java @@ -167,9 +167,9 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList final FoldingGroup group = region.getGroup(); if (group != null) { myGroups.putValue(group, region); - for (FoldingListener listener : myListeners) { - listener.onFoldRegionStateChange(region); - } + } + for (FoldingListener listener : myListeners) { + listener.onFoldRegionStateChange(region); } return true; } 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 af88b5231bd8..a2a1975a9759 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 @@ -76,6 +76,17 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi private int myActive; private boolean myUseSoftWraps; + /** + * Soft wraps need to be kept up-to-date on all editor modification (changing text, adding/removing/expanding/collapsing fold + * regions etc). Hence, we need to react to all types of target changes. However, soft wraps processing uses various information + * provided by editor and there is a possible case that that information is inconsistent during update time (e.g. fold model + * advances fold region offsets when end-user types before it, hence, fold regions data is inconsistent between the moment + * when text changes are applied to the document and fold data is actually updated). + *
+ * Current field serves as a flag that indicates if all preliminary actions necessary for successful soft wraps processing is done. + */ + private boolean myUpdateInProgress; + public SoftWrapModelImpl(@NotNull EditorEx editor) { this(editor, new SoftWrapsStorage(), new CompositeSoftWrapPainter(editor)); } @@ -271,7 +282,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @NotNull @Override public LogicalPosition visualToLogicalPosition(@NotNull VisualPosition visual) { - if (!prepareToMapping()) { + if (myUpdateInProgress || !prepareToMapping()) { return myEditor.visualToLogicalPosition(visual, false); } myActive++; @@ -287,7 +298,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @NotNull @Override public LogicalPosition offsetToLogicalPosition(int offset) { - if (!prepareToMapping()) { + if (myUpdateInProgress || !prepareToMapping()) { return myEditor.offsetToLogicalPosition(offset, false); } myActive++; @@ -302,7 +313,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @NotNull public LogicalPosition adjustLogicalPosition(LogicalPosition defaultLogical, int offset) { - if (!prepareToMapping()) { + if (myUpdateInProgress || !prepareToMapping()) { return defaultLogical; } @@ -318,7 +329,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @NotNull public VisualPosition adjustVisualPosition(@NotNull LogicalPosition logical, @NotNull VisualPosition defaultVisual) { - if (!prepareToMapping()) { + if (myUpdateInProgress || !prepareToMapping()) { return defaultVisual; } @@ -477,6 +488,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @Override public void beforeDocumentChange(DocumentEvent event) { + myUpdateInProgress = true; if (!isSoftWrappingEnabled()) { return; } @@ -487,6 +499,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @Override public void documentChanged(DocumentEvent event) { + myUpdateInProgress = false; if (!isSoftWrappingEnabled()) { return; } @@ -497,6 +510,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @Override public void onFoldRegionStateChange(@NotNull FoldRegion region) { + myUpdateInProgress = true; if (!isSoftWrappingEnabled() || !region.isValid()) { return; } @@ -507,6 +521,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @Override public void onFoldProcessingEnd() { + myUpdateInProgress = false; if (!isSoftWrappingEnabled()) { return; } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java index 6c6da2a5a619..518b073d1c14 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java @@ -199,7 +199,7 @@ public class SoftWrapApplianceManager implements FoldingListener, DocumentListen processNonFoldToken(); } else { - boolean continueProcessing = processCollapsedFoldRegion(currentFold, event); + boolean continueProcessing = processCollapsedFoldRegion(currentFold); if (!continueProcessing) { return false; } @@ -224,11 +224,10 @@ public class SoftWrapApplianceManager implements FoldingListener, DocumentListen * Encapsulates logic of processing given collapsed fold region. * * @param foldRegion target collapsed fold region to process - * @param event change event that triggered the processing * @returntrue if processing should be continued; false otherwise
*/
- private boolean processCollapsedFoldRegion(FoldRegion foldRegion, IncrementalCacheUpdateEvent event) {
- if (processOutOfDateFoldRegion(foldRegion, event)) {
+ private boolean processCollapsedFoldRegion(FoldRegion foldRegion) {
+ if (processOutOfDateFoldRegion(foldRegion)) {
return false;
}
@@ -298,11 +297,10 @@ public class SoftWrapApplianceManager implements FoldingListener, DocumentListen
* This method encapsulates logic for checking and reacting on such a situation.
*
* @param foldRegion fold region that may be out-of-date
- * @param event change event that triggered the processing
* @return true if given fold region is really out-of-date and processing should be stopped;
* false otherwise;
*/
- private boolean processOutOfDateFoldRegion(FoldRegion foldRegion, IncrementalCacheUpdateEvent event) {
+ private boolean processOutOfDateFoldRegion(FoldRegion foldRegion) {
Document document = myEditor.getDocument();
@@ -310,17 +308,11 @@ public class SoftWrapApplianceManager implements FoldingListener, DocumentListen
// case that offsets of the trailing fold regions should be updated as well.
IncrementalCacheUpdateEvent newEvent = new IncrementalCacheUpdateEvent(document);
- // We assume here that fold model is processed after soft wrap (as it needs to perform document dimensions mapping).
- // So, there is a possible case that user performed modifications at particular fold region but fold model is not updated yet
- // and IterationState returns valid fold region. Hence, we introduce a dedicated check here.
- if (!foldRegion.isValid() || (event.getExactOffsetsDiff() != 0 && foldRegion.getStartOffset() < event.getOldExactEndOffset()
- && foldRegion.getEndOffset() > event.getOldExactStartOffset()) || myContext.tokenStartOffset != foldRegion.getStartOffset())
- {
+ if (!foldRegion.isValid() || myContext.tokenStartOffset != foldRegion.getStartOffset()) {
myEventsStorage.add(document, newEvent);
return true;
}
-
if (foldRegion.getEndOffset() <= document.getTextLength()) {
return false;
}