IDEA-63036 Fold selection/code block produces visual artifacts

Soft wraps cache is recalculated after fold regions recalculation now in order to work with consistent data
This commit is contained in:
Denis Zhdanov
2010-12-16 11:59:54 +03:00
parent 62505fdf49
commit 8d5862ce7c
4 changed files with 29 additions and 22 deletions
@@ -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;
@@ -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;
}
@@ -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).
* <p/>
* 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;
}
@@ -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
* @return <code>true</code> if processing should be continued; <code>false</code> 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 <code>true</code> if given fold region is really out-of-date and processing should be stopped;
* <code>false</code> 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;
}