mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
don't invoke coordinate transformation functions while soft wrap model is in inconsistent state
This commit is contained in:
+52
-15
@@ -16,11 +16,11 @@
|
||||
package com.intellij.openapi.editor.impl.softwrap.mapping;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.LogicalPosition;
|
||||
import com.intellij.openapi.editor.VisualPosition;
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.editor.ex.util.EditorUtil;
|
||||
import com.intellij.openapi.editor.impl.EditorImpl;
|
||||
import com.intellij.openapi.editor.impl.SoftWrapModelImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -55,15 +55,15 @@ public class IncrementalCacheUpdateEvent {
|
||||
* @param event object that describes document change that caused cache update
|
||||
*/
|
||||
IncrementalCacheUpdateEvent(@NotNull DocumentEvent event, @NotNull CachingSoftWrapDataMapper mapper, @NotNull EditorImpl editor) {
|
||||
this(event.getDocument(), event.getOffset(), event.getOffset() + event.getOldLength(), event.getOffset() + event.getNewLength(), mapper, editor);
|
||||
this(event.getOffset(), event.getOffset() + event.getOldLength(), event.getOffset() + event.getNewLength(), mapper, editor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new <code>IncrementalCacheUpdateEvent</code> object for the event not changing document length
|
||||
* (like expansion of folded region).
|
||||
*/
|
||||
IncrementalCacheUpdateEvent(@NotNull Document document, int startOffset, int endOffset, @NotNull CachingSoftWrapDataMapper mapper, @NotNull EditorImpl editor) {
|
||||
this(document, startOffset, endOffset, endOffset, mapper, editor);
|
||||
IncrementalCacheUpdateEvent(int startOffset, int endOffset, @NotNull CachingSoftWrapDataMapper mapper, @NotNull EditorImpl editor) {
|
||||
this(startOffset, endOffset, endOffset, mapper, editor);
|
||||
myNewEndLogicalLine = myOldEndLogicalLine;
|
||||
}
|
||||
|
||||
@@ -82,22 +82,59 @@ public class IncrementalCacheUpdateEvent {
|
||||
myOldEndLogicalLine = myNewEndLogicalLine = Math.max(0, document.getLineCount() - 1);
|
||||
}
|
||||
|
||||
private IncrementalCacheUpdateEvent(@NotNull Document document, int startOffset, int oldEndOffset, int newEndOffset,
|
||||
private IncrementalCacheUpdateEvent(int startOffset, int oldEndOffset, int newEndOffset,
|
||||
@NotNull CachingSoftWrapDataMapper mapper, @NotNull EditorImpl editor) {
|
||||
myStartOffset = editor.myUseNewRendering ? editor.visualLineStartOffset(editor.offsetToVisualLine(startOffset) - 1) :
|
||||
mapper.getPreviousVisualLineStartOffset(startOffset);
|
||||
myMandatoryEndOffset = newEndOffset;
|
||||
myLengthDiff = newEndOffset - oldEndOffset;
|
||||
myStartLogicalPosition = editor.myUseNewRendering ? editor.offsetToLogicalPosition(myStartOffset) :
|
||||
mapper.offsetToLogicalPosition(myStartOffset);
|
||||
if (editor.myUseNewRendering) {
|
||||
myStartVisualPosition = editor.logicalToVisualPosition(myStartLogicalPosition);
|
||||
VisualLineInfo info = getVisualLineInfo(editor, startOffset, false);
|
||||
if (info.startsWithSoftWrap) {
|
||||
info = getVisualLineInfo(editor, info.startOffset, true);
|
||||
}
|
||||
myStartOffset = info.startOffset;
|
||||
myStartLogicalPosition = editor.offsetToLogicalPosition(myStartOffset);
|
||||
myStartVisualPosition = new VisualPosition(info.visualLine, 0);
|
||||
}
|
||||
else {
|
||||
myStartOffset = mapper.getPreviousVisualLineStartOffset(startOffset);
|
||||
myStartLogicalPosition = mapper.offsetToLogicalPosition(myStartOffset);
|
||||
LOG.assertTrue(myStartLogicalPosition.visualPositionAware);
|
||||
myStartVisualPosition = myStartLogicalPosition.toVisualPosition();
|
||||
}
|
||||
myOldEndLogicalLine = document.getLineNumber(oldEndOffset);
|
||||
myMandatoryEndOffset = newEndOffset;
|
||||
myLengthDiff = newEndOffset - oldEndOffset;
|
||||
myOldEndLogicalLine = editor.getDocument().getLineNumber(oldEndOffset);
|
||||
}
|
||||
|
||||
|
||||
private static VisualLineInfo getVisualLineInfo(@NotNull EditorImpl editor, int offset, boolean beforeSoftWrap) {
|
||||
Document document = editor.getDocument();
|
||||
int textLength = document.getTextLength();
|
||||
if (offset <= 0 || textLength == 0) return new VisualLineInfo(0, 0, false);
|
||||
offset = Math.min(offset, textLength);
|
||||
|
||||
int startOffset = EditorUtil.getNotFoldedLineStartOffset(editor, offset);
|
||||
|
||||
SoftWrapModelImpl softWrapModel = editor.getSoftWrapModel();
|
||||
int wrapIndex = softWrapModel.getSoftWrapIndex(offset);
|
||||
int prevSoftWrapIndex = wrapIndex < 0 ? (- wrapIndex - 2) : wrapIndex - (beforeSoftWrap ? 1 : 0);
|
||||
SoftWrap prevSoftWrap = prevSoftWrapIndex < 0 ? null : softWrapModel.getRegisteredSoftWraps().get(prevSoftWrapIndex);
|
||||
|
||||
int visualLine = document.getLineNumber(offset) - editor.getFoldingModel().getFoldedLinesCountBefore(offset) + (prevSoftWrapIndex + 1);
|
||||
int visualLineStartOffset = prevSoftWrap == null ? startOffset : Math.max(startOffset, prevSoftWrap.getStart());
|
||||
return new VisualLineInfo(visualLine,
|
||||
visualLineStartOffset,
|
||||
prevSoftWrap != null && prevSoftWrap.getStart() == visualLineStartOffset);
|
||||
}
|
||||
|
||||
private static class VisualLineInfo {
|
||||
private final int visualLine;
|
||||
private final int startOffset;
|
||||
private final boolean startsWithSoftWrap;
|
||||
|
||||
private VisualLineInfo(int visualLine, int startOffset, boolean wrap) {
|
||||
this.visualLine = visualLine;
|
||||
this.startOffset = startOffset;
|
||||
startsWithSoftWrap = wrap;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateAfterDocumentChange(@NotNull Document document) {
|
||||
|
||||
+1
-2
@@ -193,8 +193,7 @@ public class SoftWrapApplianceManager implements Dumpable {
|
||||
for (Segment range : ranges) {
|
||||
int lastOffset = lastRecalculatedOffset[0];
|
||||
if (range.getEndOffset() > lastOffset) {
|
||||
recalculateSoftWraps(new IncrementalCacheUpdateEvent(myEditor.getDocument(),
|
||||
Math.max(range.getStartOffset(), lastOffset), range.getEndOffset(),
|
||||
recalculateSoftWraps(new IncrementalCacheUpdateEvent(Math.max(range.getStartOffset(), lastOffset), range.getEndOffset(),
|
||||
myDataMapper, myEditor));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,4 +199,11 @@ public class EditorImplTest extends AbstractEditorTest {
|
||||
myEditor.getSettings().setAdditionalLinesCount(0);
|
||||
assertEquals(new Dimension(50, 30), myEditor.getContentComponent().getPreferredSize());
|
||||
}
|
||||
|
||||
public void testCollapsingRegionContainingSoftWrap() throws Exception {
|
||||
initText("abcdef abcdef");
|
||||
configureSoftWraps(10);
|
||||
addCollapsedFoldRegion(0, 13, "...");
|
||||
assertEquals(new VisualPosition(0, 3), myEditor.offsetToVisualPosition(13));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user