mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-58130 Improve editor performance during working with large files written in a single line
Make logicalPositionToOffset calculations faster for long lines (when soft wraps are enabled). Position calculations are more consistent now so this is also supposed to fix EA-53787.
This commit is contained in:
@@ -33,6 +33,7 @@ import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiLiteralExpression
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.testFramework.EditorTestUtil
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
|
||||
@@ -1087,6 +1088,35 @@ class Foo {
|
||||
assertEquals 0, expandedFoldRegionsCount
|
||||
}
|
||||
|
||||
public void "test processing of tabs inside fold regions"() {
|
||||
String text = """public class Foo {
|
||||
\tpublic static void main(String[] args) {
|
||||
\t\tjavax.swing.SwingUtilities.invokeLater(new Runnable() {
|
||||
\t\t\t@Override
|
||||
\t\t\tpublic void run() {
|
||||
\t\t\t\tSystem.out.println();
|
||||
\t\t\t}
|
||||
\t\t});
|
||||
\t}
|
||||
}""";
|
||||
configure text
|
||||
assert myFixture.editor.getFoldingModel().getCollapsedRegionAtOffset(text.indexOf("new"))
|
||||
myFixture.editor.settings.useTabCharacter = true
|
||||
EditorTestUtil.configureSoftWraps(myFixture.editor, 1000)
|
||||
myFixture.editor.caretModel.moveToOffset(text.indexOf("System"))
|
||||
myFixture.performEditorAction(IdeActions.ACTION_EDITOR_TAB)
|
||||
myFixture.checkResult("""public class Foo {
|
||||
\tpublic static void main(String[] args) {
|
||||
\t\tjavax.swing.SwingUtilities.invokeLater(new Runnable() {
|
||||
\t\t\t@Override
|
||||
\t\t\tpublic void run() {
|
||||
\t\t\t\t\t<caret>System.out.println();
|
||||
\t\t\t}
|
||||
\t\t});
|
||||
\t}
|
||||
}""");
|
||||
}
|
||||
|
||||
private int getFoldRegionsCount() {
|
||||
return myFixture.editor.foldingModel.allFoldRegions.length
|
||||
}
|
||||
|
||||
@@ -570,9 +570,15 @@ public class EditorWindowImpl extends UserDataHolderBase implements EditorWindow
|
||||
|
||||
@Override
|
||||
public int logicalPositionToOffset(@NotNull final LogicalPosition pos) {
|
||||
return logicalPositionToOffset(pos, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int logicalPositionToOffset(@NotNull LogicalPosition pos, boolean softWrapAware) {
|
||||
int lineStartOffset = myDocumentWindow.getLineStartOffset(pos.line);
|
||||
return calcOffset(pos.column, pos.line, lineStartOffset);
|
||||
}
|
||||
|
||||
private int calcLogicalColumnNumber(int offsetInLine, int lineNumber, int lineStartOffset) {
|
||||
if (myDocumentWindow.getTextLength() == 0) return 0;
|
||||
|
||||
@@ -583,13 +589,25 @@ public class EditorWindowImpl extends UserDataHolderBase implements EditorWindow
|
||||
CharSequence text = myDocumentWindow.getCharsSequence();
|
||||
return EditorUtil.calcColumnNumber(this, text, lineStartOffset, lineStartOffset +offsetInLine);
|
||||
}
|
||||
|
||||
private int calcOffset(int col, int lineNumber, int lineStartOffset) {
|
||||
if (myDocumentWindow.getTextLength() == 0) return 0;
|
||||
|
||||
int end = myDocumentWindow.getLineEndOffset(lineNumber);
|
||||
|
||||
CharSequence text = myDocumentWindow.getCharsSequence();
|
||||
return EditorUtil.calcOffset(this, text, lineStartOffset, end, col, EditorUtil.getTabSize(myDelegate), null);
|
||||
int x = getDocument().getLineNumber(lineStartOffset) == 0 ? getPrefixTextWidthInPixels() : 0;
|
||||
|
||||
// There is a possible case that target column points inside soft wrap-introduced virtual space.
|
||||
if (col <= 0) {
|
||||
return lineStartOffset;
|
||||
}
|
||||
|
||||
int result = EditorUtil.calcSoftWrapUnawareOffset(this, myDocumentWindow.getCharsSequence(), lineStartOffset, end, col,
|
||||
EditorUtil.getTabSize(myDelegate), x, new int[]{0}, null);
|
||||
if (result >= 0) {
|
||||
return result;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -178,6 +178,8 @@ public interface EditorEx extends Editor {
|
||||
@NotNull
|
||||
VisualPosition logicalToVisualPosition(@NotNull LogicalPosition logicalPos, boolean softWrapAware);
|
||||
|
||||
int logicalPositionToOffset(@NotNull LogicalPosition logicalPos, boolean softWrapAware);
|
||||
|
||||
/**
|
||||
* Creates color scheme delegate which is bound to current editor. E.g. all schema changes will update editor state.
|
||||
* @param customGlobalScheme
|
||||
|
||||
@@ -50,6 +50,14 @@ public interface SoftWrapModelEx extends SoftWrapModel {
|
||||
@NotNull
|
||||
LogicalPosition offsetToLogicalPosition(int offset);
|
||||
|
||||
/**
|
||||
* Asks current model to map given logical position to document offset
|
||||
*
|
||||
* @param logicalPosition target editor logical position
|
||||
* @return document offset for the given editor logical position
|
||||
*/
|
||||
int logicalPositionToOffset(@NotNull LogicalPosition logicalPosition);
|
||||
|
||||
/**
|
||||
* Asks current model to adjust visual position that corresponds to the given logical position if necessary.
|
||||
* <p/>
|
||||
|
||||
@@ -222,7 +222,12 @@ public final class EditorUtil {
|
||||
* @param tabSize number of desired visual columns to use for tabulation representation
|
||||
* @param debugBuffer buffer to hold debug info during the processing (if any)
|
||||
* @return given text offset that identifies the same position that is pointed by the given visual column
|
||||
*
|
||||
* @deprecated This function can give incorrect results when soft wraps are enabled in editor. It is also slow in case of
|
||||
* long document lines - {@link com.intellij.openapi.editor.Editor#logicalPositionToOffset(com.intellij.openapi.editor.LogicalPosition)}
|
||||
* should be faster when soft wraps are enabled. To be removed in IDEA 16.
|
||||
*/
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public static int calcOffset(@NotNull EditorEx editor,
|
||||
@NotNull CharSequence text,
|
||||
int start,
|
||||
@@ -291,7 +296,7 @@ public final class EditorUtil {
|
||||
* @return target offset that belongs to the <code>[start; end)</code> range and points to the target logical
|
||||
* column if any; <code>-1</code> otherwise
|
||||
*/
|
||||
private static int calcSoftWrapUnawareOffset(@NotNull Editor editor,
|
||||
public static int calcSoftWrapUnawareOffset(@NotNull Editor editor,
|
||||
@NotNull CharSequence text,
|
||||
int start,
|
||||
int end,
|
||||
|
||||
@@ -200,15 +200,14 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
final DocumentEx document = myEditor.getDocument();
|
||||
int textEnd = Math.min(document.getTextLength() - 1, Math.max(offset, myOffset) + 1);
|
||||
CharSequence text = document.getCharsSequence().subSequence(textStart, textEnd);
|
||||
StringBuilder positionToOffsetTrace = new StringBuilder();
|
||||
int inverseOffset = myEditor.logicalPositionToOffset(logicalPosition, positionToOffsetTrace);
|
||||
int inverseOffset = myEditor.logicalPositionToOffset(logicalPosition);
|
||||
LogMessageEx.error(
|
||||
LOG, "caret moved to wrong offset. Please submit a dedicated ticket and attach current editor's text to it.",
|
||||
String.format(
|
||||
"Requested: offset=%d, logical position='%s' but actual: offset=%d, logical position='%s' (%s). %s%n"
|
||||
+ "interested text [%d;%d): '%s'%n debug trace: %s%nLogical position -> offset ('%s'->'%d') trace: %s",
|
||||
+ "interested text [%d;%d): '%s'%n debug trace: %s%nLogical position -> offset ('%s'->'%d')",
|
||||
offset, logicalPosition, myOffset, myLogicalCaret, positionByOffsetAfterMove, myEditor.dumpState(),
|
||||
textStart, textEnd, text, debugBuffer, logicalPosition, inverseOffset, positionToOffsetTrace
|
||||
textStart, textEnd, text, debugBuffer, logicalPosition, inverseOffset
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
+10
-4
@@ -19,7 +19,6 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ex.util.EditorUtil;
|
||||
import gnu.trove.TObjectIntHashMap;
|
||||
import org.intellij.lang.annotations.JdkConstants;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Not thread-safe. Performs caching of char widths, so cache reset must be invoked (via {@link #clearSymbolWidthCache()} method) when
|
||||
@@ -52,8 +51,8 @@ public class DefaultEditorTextRepresentationHelper implements EditorTextRepresen
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toVisualColumnSymbolsNumber(@NotNull CharSequence text, int start, int end, int x) {
|
||||
return EditorUtil.textWidthInColumns(myEditor, text, start, end, x);
|
||||
public int toVisualColumnSymbolsNumber(int start, int end, int x) {
|
||||
return EditorUtil.textWidthInColumns(myEditor, myEditor.getDocument().getImmutableCharSequence(), start, end, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,7 +66,14 @@ public class DefaultEditorTextRepresentationHelper implements EditorTextRepresen
|
||||
}
|
||||
|
||||
@Override
|
||||
public int textWidth(@NotNull CharSequence text, int start, int end, int fontType, int x) {
|
||||
public int calcSoftWrapUnawareOffset(int startOffset, int endOffset, int startColumn, int column, int startX) {
|
||||
return EditorUtil.calcSoftWrapUnawareOffset(myEditor, myEditor.getDocument().getImmutableCharSequence(), startOffset, endOffset,
|
||||
column, EditorUtil.getTabSize(myEditor), startX, new int[]{startColumn}, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int textWidth(int start, int end, int fontType, int x) {
|
||||
CharSequence text = myEditor.getDocument().getImmutableCharSequence();
|
||||
int startToUse = start;
|
||||
for (int i = end - 1; i >= start; i--) {
|
||||
if (text.charAt(i) == '\n') {
|
||||
|
||||
@@ -3656,11 +3656,14 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
|
||||
@Override
|
||||
public int logicalPositionToOffset(@NotNull LogicalPosition pos) {
|
||||
return logicalPositionToOffset(pos, null);
|
||||
return logicalPositionToOffset(pos, true);
|
||||
}
|
||||
|
||||
|
||||
public int logicalPositionToOffset(@NotNull LogicalPosition pos, @Nullable StringBuilder debugBuffer) {
|
||||
@Override
|
||||
public int logicalPositionToOffset(@NotNull LogicalPosition pos, boolean softWrapAware) {
|
||||
if (softWrapAware) {
|
||||
return mySoftWrapModel.logicalPositionToOffset(pos);
|
||||
}
|
||||
assertReadAccess();
|
||||
if (myDocument.getLineCount() == 0) return 0;
|
||||
|
||||
@@ -3675,9 +3678,15 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
if (pos.column == 0) return start;
|
||||
int end = myDocument.getLineEndOffset(pos.line);
|
||||
|
||||
CharSequence text = myDocument.getImmutableCharSequence();
|
||||
int x = getDocument().getLineNumber(start) == 0 ? getPrefixTextWidthInPixels() : 0;
|
||||
|
||||
return EditorUtil.calcOffset(this, text, start, end, pos.column, EditorUtil.getTabSize(this), debugBuffer);
|
||||
int result = EditorUtil.calcSoftWrapUnawareOffset(this, myDocument.getImmutableCharSequence(), start, end, pos.column,
|
||||
EditorUtil.getTabSize(this), x, new int[]{0}, null);
|
||||
if (result >= 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return end;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+16
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.intellij.openapi.editor.impl;
|
||||
|
||||
import org.intellij.lang.annotations.JdkConstants;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Strategy interface for various utility methods used for representing document text at the editor.
|
||||
@@ -37,13 +36,12 @@ public interface EditorTextRepresentationHelper {
|
||||
* Allows to answer how many visual columns is necessary for representing target fragment of the given text assuming
|
||||
* that it belongs to the single visual line and should be shown at given <code>'x'</code> offset from the visual line start.
|
||||
*
|
||||
* @param text target text holder
|
||||
* @param start start offset of the target text sub-sequence (inclusive)
|
||||
* @param end end offset of the target text sub-sequence (exclusive)
|
||||
* @param x <code>'x'</code> offset from the visual line start
|
||||
* @return number of visual columns necessary for the target text sub-sequence representation
|
||||
*/
|
||||
int toVisualColumnSymbolsNumber(@NotNull CharSequence text, int start, int end, int x);
|
||||
int toVisualColumnSymbolsNumber(int start, int end, int x);
|
||||
|
||||
/**
|
||||
* Allows to retrieve width (in pixels) necessary to represent given region (<code>[start; end)</code>) starting
|
||||
@@ -52,17 +50,16 @@ public interface EditorTextRepresentationHelper {
|
||||
* <b>Note:</b> target region is allows to contain line feeds, the width is calculated as a difference between <code>'x'</code>
|
||||
* coordinates of the last and first symbols.
|
||||
*
|
||||
* @param text target text holder
|
||||
* @param start start offset of the target text sub-sequence (inclusive)
|
||||
* @param end end offset of the target text sub-sequence (exclusive)
|
||||
* @param fontType font type used for the given substring representation
|
||||
* @param x <code>'x'</code> offset from the visual line start
|
||||
* @return width in pixels necessary for the target text sub-sequence representation
|
||||
*/
|
||||
int textWidth(@NotNull CharSequence text, int start, int end, @JdkConstants.FontStyle int fontType, int x);
|
||||
int textWidth(int start, int end, @JdkConstants.FontStyle int fontType, int x);
|
||||
|
||||
/**
|
||||
* This is specification of {@link #textWidth(CharSequence, int, int, int, int)} in case of the single character
|
||||
* This is specification of {@link #textWidth(int, int, int, int)} in case of the single character
|
||||
* (in comparison with the situation when we need to calculate width of particular text).
|
||||
* <p/>
|
||||
* <b>Note:</b> it's assumed that given symbols is a regular one (non-tabulation, non-line feed etc).
|
||||
@@ -72,4 +69,16 @@ public interface EditorTextRepresentationHelper {
|
||||
* @return width in pixels necessary for the target char representation
|
||||
*/
|
||||
int charWidth(char c, @JdkConstants.FontStyle int fontType);
|
||||
|
||||
/**
|
||||
* Translates column number to offset in the given document interval (which is assumed not to contain line breaks or soft wraps).
|
||||
*
|
||||
* @param startOffset interval start offset
|
||||
* @param endOffset interval end offset
|
||||
* @param startColumn interval start column
|
||||
* @param column target column
|
||||
* @param startX interval start visual coordinate
|
||||
* @return offset, corresponding to the given column, in the range [startOffset; endOffset), or -1 if such offset doesn't exist
|
||||
*/
|
||||
int calcSoftWrapUnawareOffset(int startOffset, int endOffset, int startColumn, int column, int startX);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.openapi.editor.impl;
|
||||
|
||||
import com.intellij.diagnostic.Dumpable;
|
||||
import com.intellij.injected.editor.EditorWindow;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -62,6 +63,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#" + SoftWrapModelImpl.class.getName());
|
||||
|
||||
private final LogicalPositionToOffsetTask myLogicalToOffsetTask = new LogicalPositionToOffsetTask();
|
||||
private final OffsetToLogicalTask myOffsetToLogicalTask = new OffsetToLogicalTask();
|
||||
private final VisualToLogicalTask myVisualToLogicalTask = new VisualToLogicalTask();
|
||||
private final LogicalToVisualTask myLogicalToVisualTask = new LogicalToVisualTask();
|
||||
@@ -148,8 +150,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
|
||||
}
|
||||
}
|
||||
});
|
||||
EditorSettings settings = myEditor.getSettings();
|
||||
myUseSoftWraps = settings.isUseSoftWraps();
|
||||
myUseSoftWraps = areSoftWrapsEnabledInEditor();
|
||||
myFontPreferences = myEditor.getColorsScheme().getFontPreferences();
|
||||
|
||||
editor.addPropertyChangeListener(this);
|
||||
@@ -157,13 +158,16 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
|
||||
myApplianceManager.addListener(myDataMapper);
|
||||
}
|
||||
|
||||
private boolean areSoftWrapsEnabledInEditor() {
|
||||
return !(myEditor instanceof EditorWindow) && myEditor.getSettings().isUseSoftWraps();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on editor settings change. Current model is expected to drop all cached information about the settings if any.
|
||||
*/
|
||||
public void reinitSettings() {
|
||||
boolean softWrapsUsedBefore = myUseSoftWraps;
|
||||
EditorSettings settings = myEditor.getSettings();
|
||||
myUseSoftWraps = settings.isUseSoftWraps();
|
||||
myUseSoftWraps = areSoftWrapsEnabledInEditor();
|
||||
|
||||
int tabWidthBefore = myTabWidth;
|
||||
myTabWidth = EditorUtil.getTabSize(myEditor);
|
||||
@@ -372,6 +376,21 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int logicalPositionToOffset(@NotNull LogicalPosition logicalPosition) {
|
||||
if (myBulkUpdateInProgress || myUpdateInProgress || !prepareToMapping()) {
|
||||
return myEditor.logicalPositionToOffset(logicalPosition, false);
|
||||
}
|
||||
myActive++;
|
||||
try {
|
||||
myLogicalToOffsetTask.input = logicalPosition;
|
||||
executeSafely(myLogicalToOffsetTask);
|
||||
return myLogicalToOffsetTask.output;
|
||||
} finally {
|
||||
myActive--;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public LogicalPosition adjustLogicalPosition(LogicalPosition defaultLogical, int offset) {
|
||||
if (myBulkUpdateInProgress || myUpdateInProgress || !prepareToMapping()) {
|
||||
@@ -788,6 +807,22 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
|
||||
}
|
||||
}
|
||||
|
||||
private class LogicalPositionToOffsetTask implements SoftWrapAwareTask {
|
||||
|
||||
public LogicalPosition input;
|
||||
public int output;
|
||||
|
||||
@Override
|
||||
public void run(boolean softWrapAware) throws IllegalStateException {
|
||||
output = softWrapAware ? myDataMapper.logicalPositionToOffset(input) : myEditor.logicalPositionToOffset(input, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "mapping from logical position (" + input + ") to offset";
|
||||
}
|
||||
}
|
||||
|
||||
private class FoldProcessingEndTask implements SoftWrapAwareTask {
|
||||
@Override
|
||||
public void run(boolean softWrapAware) {
|
||||
|
||||
+10
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -62,4 +62,13 @@ public interface SoftWrapDataMapper {
|
||||
*/
|
||||
VisualPosition logicalToVisualPosition(@NotNull LogicalPosition logical, @NotNull VisualPosition softWrapUnawareVisual)
|
||||
throws IllegalStateException;
|
||||
|
||||
/**
|
||||
* Maps given logical position to corresponding offset.
|
||||
*
|
||||
* @param logical logical position to map
|
||||
* @return offset that corresponds to the given logical position
|
||||
* @throws IllegalStateException if it's not possible to perform a mapping
|
||||
*/
|
||||
int logicalPositionToOffset(@NotNull LogicalPosition logical) throws IllegalStateException;
|
||||
}
|
||||
|
||||
+7
-4
@@ -16,9 +16,9 @@
|
||||
package com.intellij.openapi.editor.impl.softwrap.mapping;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.FoldRegion;
|
||||
import com.intellij.openapi.editor.LogicalPosition;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.impl.softwrap.SoftWrapsStorage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -37,7 +37,7 @@ import java.util.List;
|
||||
*/
|
||||
abstract class AbstractMappingStrategy<T> implements MappingStrategy<T> {
|
||||
|
||||
protected final Editor myEditor;
|
||||
protected final EditorEx myEditor;
|
||||
protected final SoftWrapsStorage myStorage;
|
||||
protected final List<CacheEntry> myCache;
|
||||
|
||||
@@ -46,7 +46,7 @@ abstract class AbstractMappingStrategy<T> implements MappingStrategy<T> {
|
||||
private T myEagerMatch;
|
||||
private int myLastEntryOffset;
|
||||
|
||||
AbstractMappingStrategy(@NotNull Editor editor,
|
||||
AbstractMappingStrategy(@NotNull EditorEx editor,
|
||||
@NotNull SoftWrapsStorage storage,
|
||||
@NotNull List<CacheEntry> cache)
|
||||
{
|
||||
@@ -154,7 +154,11 @@ abstract class AbstractMappingStrategy<T> implements MappingStrategy<T> {
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
advancePositionOnFolding(position, foldRegion);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void advancePositionOnFolding(@NotNull EditorPosition position, @NotNull FoldRegion foldRegion) {
|
||||
Document document = myEditor.getDocument();
|
||||
int endOffsetLogicalLine = document.getLineNumber(foldRegion.getEndOffset());
|
||||
if (position.logicalLine != endOffsetLogicalLine) {
|
||||
@@ -171,7 +175,6 @@ abstract class AbstractMappingStrategy<T> implements MappingStrategy<T> {
|
||||
}
|
||||
|
||||
position.advance(foldRegion, collapsedSymbolsWidthInColumns);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+9
-1
@@ -67,6 +67,7 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw
|
||||
private final CacheState myBeforeChangeState = new CacheState();
|
||||
private final CacheState myAfterChangeState = new CacheState();
|
||||
|
||||
private final LogicalToOffsetCalculationStrategy myLogicalToOffsetStrategy;
|
||||
private final OffsetToLogicalCalculationStrategy myOffsetToLogicalStrategy;
|
||||
private final VisualToLogicalCalculationStrategy myVisualToLogicalStrategy;
|
||||
private final EditorEx myEditor;
|
||||
@@ -79,6 +80,7 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw
|
||||
myStorage = storage;
|
||||
mySearchKey = new CacheEntry(0, editor);
|
||||
|
||||
myLogicalToOffsetStrategy = new LogicalToOffsetCalculationStrategy(editor, storage, myCache);
|
||||
myOffsetToLogicalStrategy = new OffsetToLogicalCalculationStrategy(editor, storage, myCache);
|
||||
myVisualToLogicalStrategy = new VisualToLogicalCalculationStrategy(editor, storage, myCache);
|
||||
}
|
||||
@@ -101,6 +103,12 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw
|
||||
return calculate(myOffsetToLogicalStrategy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int logicalPositionToOffset(@NotNull LogicalPosition logical) throws IllegalStateException {
|
||||
myLogicalToOffsetStrategy.init(logical);
|
||||
return calculate(myLogicalToOffsetStrategy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisualPosition logicalToVisualPosition(@NotNull LogicalPosition logical, @NotNull VisualPosition softWrapUnawareVisual)
|
||||
throws IllegalStateException
|
||||
@@ -144,7 +152,7 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw
|
||||
// Count soft wrap column offset only if it's located at the same line as the target offset.
|
||||
if (column < 0 && softWrap.getStart() >= targetLogicalLineStartOffset) {
|
||||
column = softWrap.getIndentInColumns() + SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor).toVisualColumnSymbolsNumber(
|
||||
myEditor.getDocument().getCharsSequence(), softWrap.getStart(), maxOffset, softWrap.getIndentInPixels()
|
||||
softWrap.getStart(), maxOffset, softWrap.getIndentInPixels()
|
||||
);
|
||||
|
||||
// Count lines introduced by the current soft wrap. We assume that every soft wrap has a single line feed.
|
||||
|
||||
+2
-8
@@ -144,10 +144,7 @@ class EditorPosition implements Cloneable {
|
||||
// Single-line fold region.
|
||||
if (collapsedSymbolsWidthInColumns < 0) {
|
||||
collapsedSymbolsWidthInColumns = SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor)
|
||||
.toVisualColumnSymbolsNumber(document.getCharsSequence(),
|
||||
foldRegion.getStartOffset(),
|
||||
foldRegion.getEndOffset(),
|
||||
x);
|
||||
.toVisualColumnSymbolsNumber(foldRegion.getStartOffset(), foldRegion.getEndOffset(), x);
|
||||
}
|
||||
logicalColumn += collapsedSymbolsWidthInColumns;
|
||||
foldingColumnDiff += placeholder.length() - collapsedSymbolsWidthInColumns;
|
||||
@@ -156,10 +153,7 @@ class EditorPosition implements Cloneable {
|
||||
// Multi-line fold region.
|
||||
if (collapsedSymbolsWidthInColumns < 0) {
|
||||
collapsedSymbolsWidthInColumns = SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor)
|
||||
.toVisualColumnSymbolsNumber(document.getCharsSequence(),
|
||||
foldRegion.getStartOffset(),
|
||||
foldRegion.getEndOffset(),
|
||||
0);
|
||||
.toVisualColumnSymbolsNumber(foldRegion.getStartOffset(), foldRegion.getEndOffset(), 0);
|
||||
}
|
||||
int linesDiff = endOffsetLogicalLine - logicalLine;
|
||||
logicalLine += linesDiff;
|
||||
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.editor.impl.softwrap.mapping;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.FoldRegion;
|
||||
import com.intellij.openapi.editor.LogicalPosition;
|
||||
import com.intellij.openapi.editor.SoftWrap;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.impl.SoftWrapModelImpl;
|
||||
import com.intellij.openapi.editor.impl.softwrap.SoftWrapsStorage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class LogicalToOffsetCalculationStrategy extends AbstractMappingStrategy<Integer> {
|
||||
|
||||
private LogicalPosition targetPosition;
|
||||
|
||||
LogicalToOffsetCalculationStrategy(@NotNull EditorEx editor, @NotNull SoftWrapsStorage storage, @NotNull List<CacheEntry> cache) {
|
||||
super(editor, storage, cache);
|
||||
}
|
||||
|
||||
void init(LogicalPosition logical) {
|
||||
CacheEntry entry = MappingUtil.getCacheEntryForLogicalPosition(logical, myCache);
|
||||
if (entry == null) {
|
||||
if (logical.line >= myEditor.getDocument().getLineCount()) {
|
||||
setEagerMatch(myEditor.getDocument().getTextLength());
|
||||
}
|
||||
else {
|
||||
setEagerMatch(Math.min(myEditor.getDocument().getLineStartOffset(logical.line) + logical.column,
|
||||
myEditor.getDocument().getLineEndOffset(logical.line)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (entry.endLogicalLine == logical.line && entry.endLogicalColumn <= logical.column) {
|
||||
setEagerMatch(entry.endOffset);
|
||||
return;
|
||||
}
|
||||
reset();
|
||||
targetPosition = logical;
|
||||
setTargetEntry(entry, true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Integer buildIfExceeds(EditorPosition position, int offset) {
|
||||
if (position.logicalLine != targetPosition.line) {
|
||||
return null;
|
||||
}
|
||||
int result = position.offset + targetPosition.column - position.logicalColumn;
|
||||
return result > offset ? null : result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer processFoldRegion(@NotNull EditorPosition position, @NotNull FoldRegion foldRegion) {
|
||||
int startLine = position.logicalLine;
|
||||
int startColumn = position.logicalColumn;
|
||||
int startX = position.x;
|
||||
|
||||
advancePositionOnFolding(position, foldRegion);
|
||||
|
||||
if (position.logicalLine < targetPosition.line
|
||||
|| position.logicalLine == targetPosition.line && position.logicalColumn <= targetPosition.column) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Document document = myEditor.getDocument();
|
||||
int lineEndOffset = document.getLineEndOffset(targetPosition.line);
|
||||
int result = SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor)
|
||||
.calcSoftWrapUnawareOffset(targetPosition.line == startLine ? foldRegion.getStartOffset()
|
||||
: document.getLineStartOffset(targetPosition.line),
|
||||
lineEndOffset,
|
||||
targetPosition.line == startLine ? startColumn : 0,
|
||||
targetPosition.column,
|
||||
targetPosition.line == startLine ? startX : 0);
|
||||
return result < 0 ? lineEndOffset : result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Integer buildIfExceeds(@NotNull EditorPosition position, @NotNull FoldRegion foldRegion) {
|
||||
throw new RuntimeException("Unexpected invocation");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Integer buildIfExceeds(EditorPosition position, TabData tabData) {
|
||||
if (position.logicalLine != targetPosition.line) {
|
||||
return null;
|
||||
}
|
||||
return position.logicalColumn + tabData.widthInColumns > targetPosition.column ? position.offset : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Integer processSoftWrap(@NotNull EditorPosition position, SoftWrap softWrap) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Integer build(@NotNull EditorPosition position) {
|
||||
return position.offset + targetPosition.column - position.logicalColumn;
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -16,6 +16,7 @@
|
||||
package com.intellij.openapi.editor.impl.softwrap.mapping;
|
||||
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.impl.SoftWrapModelImpl;
|
||||
import com.intellij.openapi.editor.impl.softwrap.SoftWrapsStorage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -31,7 +32,7 @@ class LogicalToVisualMappingStrategy extends AbstractMappingStrategy<VisualPosit
|
||||
|
||||
private LogicalPosition myTargetLogical;
|
||||
|
||||
LogicalToVisualMappingStrategy(@NotNull LogicalPosition logical, @NotNull Editor editor, @NotNull SoftWrapsStorage storage,
|
||||
LogicalToVisualMappingStrategy(@NotNull LogicalPosition logical, @NotNull EditorEx editor, @NotNull SoftWrapsStorage storage,
|
||||
@NotNull List<CacheEntry> cache)
|
||||
throws IllegalStateException
|
||||
{
|
||||
@@ -122,7 +123,7 @@ class LogicalToVisualMappingStrategy extends AbstractMappingStrategy<VisualPosit
|
||||
if (data == null) {
|
||||
int xStart = myEditor.getDocument().getLineNumber(foldRegion.getStartOffset()) == foldEndLine ? context.x : 0;
|
||||
foldEndColumn = SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor).toVisualColumnSymbolsNumber(
|
||||
myEditor.getDocument().getCharsSequence(), foldRegion.getStartOffset(), foldRegion.getEndOffset(), xStart
|
||||
foldRegion.getStartOffset(), foldRegion.getEndOffset(), xStart
|
||||
);
|
||||
} else {
|
||||
foldEndColumn = data.getCollapsedSymbolsWidthInColumns();
|
||||
|
||||
+32
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,9 @@
|
||||
package com.intellij.openapi.editor.impl.softwrap.mapping;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.LogicalPosition;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -79,4 +82,32 @@ public class MappingUtil {
|
||||
return -(start + 1);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static CacheEntry getCacheEntryForLogicalPosition(@NotNull LogicalPosition position, @NotNull List<CacheEntry> cache) {
|
||||
int start = 0;
|
||||
int end = cache.size() - 1;
|
||||
|
||||
while (start <= end) {
|
||||
int i = (end + start) >>> 1;
|
||||
CacheEntry cacheEntry = cache.get(i);
|
||||
if (cacheEntry.startLogicalLine < position.line
|
||||
|| cacheEntry.startLogicalLine == position.line && cacheEntry.startLogicalColumn < position.column) {
|
||||
start = i + 1;
|
||||
continue;
|
||||
}
|
||||
if (cacheEntry.startLogicalLine > position.line
|
||||
|| cacheEntry.startLogicalLine == position.line && cacheEntry.startLogicalColumn > position.column) {
|
||||
end = i - 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
return assertEnd(position, cache.get(i));
|
||||
}
|
||||
return end < 0 ? null : assertEnd(position, cache.get(end));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static CacheEntry assertEnd(@NotNull LogicalPosition position, @NotNull CacheEntry entry) {
|
||||
return position.line <= entry.endLogicalLine ? entry : null;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -16,6 +16,7 @@
|
||||
package com.intellij.openapi.editor.impl.softwrap.mapping;
|
||||
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.impl.SoftWrapModelImpl;
|
||||
import com.intellij.openapi.editor.impl.softwrap.SoftWrapsStorage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -31,7 +32,7 @@ class OffsetToLogicalCalculationStrategy extends AbstractMappingStrategy<Logical
|
||||
|
||||
private int myTargetOffset;
|
||||
|
||||
OffsetToLogicalCalculationStrategy(@NotNull Editor editor, @NotNull SoftWrapsStorage storage, @NotNull List<CacheEntry> cache)
|
||||
OffsetToLogicalCalculationStrategy(@NotNull EditorEx editor, @NotNull SoftWrapsStorage storage, @NotNull List<CacheEntry> cache)
|
||||
{
|
||||
super(editor, storage, cache);
|
||||
}
|
||||
@@ -157,13 +158,13 @@ class OffsetToLogicalCalculationStrategy extends AbstractMappingStrategy<Logical
|
||||
if (targetLogicalLine == position.logicalLine) {
|
||||
// Target offset is located on the same logical line as folding start.
|
||||
position.logicalColumn += SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor).toVisualColumnSymbolsNumber(
|
||||
document.getCharsSequence(), foldRegion.getStartOffset(), myTargetOffset, position.x
|
||||
foldRegion.getStartOffset(), myTargetOffset, position.x
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Target offset is located on a different line with folding start.
|
||||
position.logicalColumn = SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor).toVisualColumnSymbolsNumber(
|
||||
document.getCharsSequence(), foldRegion.getStartOffset(), myTargetOffset, 0
|
||||
foldRegion.getStartOffset(), myTargetOffset, 0
|
||||
);
|
||||
position.softWrapColumnDiff = 0;
|
||||
int linesDiff = document.getLineNumber(myTargetOffset) - document.getLineNumber(foldRegion.getStartOffset());
|
||||
|
||||
+2
-1
@@ -16,6 +16,7 @@
|
||||
package com.intellij.openapi.editor.impl.softwrap.mapping;
|
||||
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.impl.softwrap.SoftWrapsStorage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -32,7 +33,7 @@ class VisualToLogicalCalculationStrategy extends AbstractMappingStrategy<Logical
|
||||
private final CacheEntry mySearchKey;
|
||||
private VisualPosition myTargetVisual;
|
||||
|
||||
VisualToLogicalCalculationStrategy(@NotNull Editor editor, @NotNull SoftWrapsStorage storage, @NotNull List<CacheEntry> cache)
|
||||
VisualToLogicalCalculationStrategy(@NotNull EditorEx editor, @NotNull SoftWrapsStorage storage, @NotNull List<CacheEntry> cache)
|
||||
{
|
||||
super(editor, storage, cache);
|
||||
mySearchKey = new CacheEntry(0, editor);
|
||||
|
||||
+29
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.intellij.openapi.editor.impl.softwrap;
|
||||
|
||||
import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
@@ -24,23 +23,26 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public class MockEditorTextRepresentationHelper implements EditorTextRepresentationHelper {
|
||||
|
||||
private final CharSequence myText;
|
||||
private final int mySpaceSizeInPixels;
|
||||
private final int myTabSizeInColumns;
|
||||
|
||||
public MockEditorTextRepresentationHelper(int spaceSizeInPixels, int tabSizeInColumns) {
|
||||
public MockEditorTextRepresentationHelper(CharSequence text, int spaceSizeInPixels, int tabSizeInColumns) {
|
||||
myText = text;
|
||||
mySpaceSizeInPixels = spaceSizeInPixels;
|
||||
myTabSizeInColumns = tabSizeInColumns;
|
||||
}
|
||||
|
||||
public int toVisualColumnSymbolsNumber(char c, int x) {
|
||||
return toVisualColumnSymbolsNumber(new String(new char[] {c}), 0, 1, x);
|
||||
return new MockEditorTextRepresentationHelper(new String(new char[] {c}), mySpaceSizeInPixels, myTabSizeInColumns)
|
||||
.toVisualColumnSymbolsNumber(0, 1, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toVisualColumnSymbolsNumber(@NotNull CharSequence text, int start, int end, int x) {
|
||||
public int toVisualColumnSymbolsNumber(int start, int end, int x) {
|
||||
int result = 0;
|
||||
for (int i = start; i < end; i++) {
|
||||
char c = text.charAt(i);
|
||||
char c = myText.charAt(i);
|
||||
if (c == '\n') {
|
||||
result = 0;
|
||||
x = 0;
|
||||
@@ -57,10 +59,10 @@ public class MockEditorTextRepresentationHelper implements EditorTextRepresentat
|
||||
}
|
||||
|
||||
@Override
|
||||
public int textWidth(@NotNull CharSequence text, int start, int end, int fontType, int x) {
|
||||
public int textWidth(int start, int end, int fontType, int x) {
|
||||
int result = 0;
|
||||
for (int i = start; i < end; i++) {
|
||||
char c = text.charAt(i);
|
||||
char c = myText.charAt(i);
|
||||
switch (c) {
|
||||
case '\n': result = 0; break;
|
||||
default: result += charWidth(c, result);
|
||||
@@ -79,4 +81,23 @@ public class MockEditorTextRepresentationHelper implements EditorTextRepresentat
|
||||
return mySpaceSizeInPixels;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calcSoftWrapUnawareOffset(int startOffset, int endOffset, int startColumn, int targetColumn, int startX) {
|
||||
int x = startX;
|
||||
int column = startColumn;
|
||||
for (int i = startOffset; i < endOffset; i++) {
|
||||
if (column == targetColumn) {
|
||||
return i;
|
||||
}
|
||||
char c = myText.charAt(i);
|
||||
int width = charWidth(c, x);
|
||||
column += width / mySpaceSizeInPixels;
|
||||
if (width % mySpaceSizeInPixels > 0) {
|
||||
column++;
|
||||
}
|
||||
x += width;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
+9
-8
@@ -104,6 +104,7 @@ public class CachingSoftWrapDataMapperTest {
|
||||
private Mockery myMockery;
|
||||
private EditorEx myEditor;
|
||||
private DocumentEx myDocument;
|
||||
private StringBuilder myChars;
|
||||
private SoftWrapsStorage myStorage;
|
||||
private SoftWrapModelEx mySoftWrapModel;
|
||||
private FoldingModelEx myFoldingModel;
|
||||
@@ -115,6 +116,7 @@ public class CachingSoftWrapDataMapperTest {
|
||||
|
||||
myEditor = myMockery.mock(EditorEx.class);
|
||||
myDocument = myMockery.mock(DocumentEx.class);
|
||||
myChars = new StringBuilder();
|
||||
myStorage = new SoftWrapsStorage();
|
||||
mySoftWrapModel = myMockery.mock(SoftWrapModelEx.class);
|
||||
myFoldingModel = myMockery.mock(FoldingModelEx.class);
|
||||
@@ -122,7 +124,7 @@ public class CachingSoftWrapDataMapperTest {
|
||||
final Project project = myMockery.mock(Project.class);
|
||||
final SoftWrapPainter painter = myMockery.mock(SoftWrapPainter.class);
|
||||
|
||||
myRepresentationHelper = new MockEditorTextRepresentationHelper(SPACE_SIZE, TAB_SIZE);
|
||||
myRepresentationHelper = new MockEditorTextRepresentationHelper(myChars, SPACE_SIZE, TAB_SIZE);
|
||||
|
||||
myMockery.checking(new Expectations() {{
|
||||
// Document
|
||||
@@ -584,19 +586,19 @@ public class CachingSoftWrapDataMapperTest {
|
||||
allowing(myDocument).getCharsSequence(); will(new CustomAction("getCharsSequence()") {
|
||||
@Override
|
||||
public Object invoke(Invocation invocation) throws Throwable {
|
||||
return context.document;
|
||||
return myChars;
|
||||
}
|
||||
});
|
||||
allowing(myDocument).getText(); will(new CustomAction("getCharsSequence()") {
|
||||
@Override
|
||||
public Object invoke(Invocation invocation) throws Throwable {
|
||||
return context.document.toString();
|
||||
return myChars.toString();
|
||||
}
|
||||
});
|
||||
allowing(myDocument).getTextLength(); will(new CustomAction("getTextLength()") {
|
||||
@Override
|
||||
public Object invoke(Invocation invocation) throws Throwable {
|
||||
return context.document.length();
|
||||
return myChars.length();
|
||||
}
|
||||
});
|
||||
}});
|
||||
@@ -629,7 +631,7 @@ public class CachingSoftWrapDataMapperTest {
|
||||
context.onNewSymbol(c);
|
||||
}
|
||||
|
||||
myLineRanges.add(new TextRange(context.logicalLineStartOffset, context.document.length()));
|
||||
myLineRanges.add(new TextRange(context.logicalLineStartOffset, myChars.length()));
|
||||
}
|
||||
|
||||
private static boolean isSoftWrapStart(String document, int index) {
|
||||
@@ -685,7 +687,6 @@ public class CachingSoftWrapDataMapperTest {
|
||||
|
||||
private class TestEditorPosition extends EditorPosition {
|
||||
private final StringBuilder mySoftWrapBuffer = new StringBuilder();
|
||||
final StringBuilder document = new StringBuilder();
|
||||
|
||||
EditorPosition lineStartPosition;
|
||||
|
||||
@@ -741,7 +742,7 @@ public class CachingSoftWrapDataMapperTest {
|
||||
insideFolding = false;
|
||||
MockFoldRegion foldRegion = new MockFoldRegion(foldingStartOffset, offset);
|
||||
myFoldRegions.add(foldRegion);
|
||||
myMapper.onCollapsedFoldRegion(foldRegion, myRepresentationHelper.toVisualColumnSymbolsNumber(document, foldingStartOffset, offset, prevX), foldingStartVisualLine);
|
||||
myMapper.onCollapsedFoldRegion(foldRegion, myRepresentationHelper.toVisualColumnSymbolsNumber(foldingStartOffset, offset, prevX), foldingStartVisualLine);
|
||||
}
|
||||
|
||||
public void onNewSymbol(char c) {
|
||||
@@ -868,7 +869,7 @@ public class CachingSoftWrapDataMapperTest {
|
||||
}
|
||||
|
||||
private void onNonSoftWrapSymbol(char c) {
|
||||
document.append(c);
|
||||
myChars.append(c);
|
||||
if (c == '\n') {
|
||||
myLineRanges.add(new TextRange(logicalLineStartOffset, offset));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user