diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/DefaultEditorTextRepresentationHelper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/DefaultEditorTextRepresentationHelper.java index 790256ccfcd5..204c3c99a4d2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/DefaultEditorTextRepresentationHelper.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/DefaultEditorTextRepresentationHelper.java @@ -19,8 +19,6 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ex.util.EditorUtil; import org.jetbrains.annotations.NotNull; -import java.awt.*; - /** * @author Denis Zhdanov * @since Jul 27, 2010 4:06:27 PM @@ -39,7 +37,7 @@ public class DefaultEditorTextRepresentationHelper implements EditorTextRepresen } @Override - public int textWidth(@NotNull CharSequence text, int start, int end, int x) { - return EditorUtil.textWidth(myEditor, text, start, end, Font.PLAIN, x); + public int textWidth(@NotNull CharSequence text, int start, int end, int fontType, int x) { + return EditorUtil.textWidth(myEditor, text, start, end, fontType, x); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorTextRepresentationHelper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorTextRepresentationHelper.java index fcf97a1f59be..640cfdc38f52 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorTextRepresentationHelper.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorTextRepresentationHelper.java @@ -48,11 +48,12 @@ public interface EditorTextRepresentationHelper { * Note: target region is allows to contain line feeds, the width is calculated as a difference between 'x' * 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 x 'x' offset from the visual line start - * @return width in pixels necessary for the target text sub-sequence representation + * @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 'x' 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, int x); + int textWidth(@NotNull CharSequence text, int start, int end, int fontType, int x); } 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 dbc0f41192d5..c1283a0b4a02 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 @@ -58,10 +58,14 @@ public class SoftWrapModelImpl implements SoftWrapModelEx { } public SoftWrapModelImpl(@NotNull final EditorEx editor, @NotNull SoftWrapsStorage storage, @NotNull SoftWrapPainter painter) { + this(editor, storage, painter, new DefaultEditorTextRepresentationHelper(editor)); + } + + public SoftWrapModelImpl(@NotNull final EditorEx editor, @NotNull SoftWrapsStorage storage, @NotNull SoftWrapPainter painter, + EditorTextRepresentationHelper representationHelper) { this( - editor, storage, painter, new DefaultSoftWrapApplianceManager(storage, editor, painter), - new SoftWrapDataMapper(editor, storage, new DefaultEditorTextRepresentationHelper(editor)), - new SoftWrapDocumentChangeManager(editor, storage) + editor, storage, painter, new DefaultSoftWrapApplianceManager(storage, editor, painter, representationHelper), + new SoftWrapDataMapper(editor, storage, representationHelper), new SoftWrapDocumentChangeManager(editor, storage) ); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/DefaultSoftWrapApplianceManager.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/DefaultSoftWrapApplianceManager.java index 89cd087c580f..ae37f75e8c83 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/DefaultSoftWrapApplianceManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/DefaultSoftWrapApplianceManager.java @@ -20,6 +20,7 @@ import com.intellij.openapi.editor.VisualPosition; import com.intellij.openapi.editor.actions.EditorActionUtil; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -103,16 +104,22 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager private final TIntHashSet myProcessedLogicalLines = new TIntHashSet(); - private final SoftWrapsStorage myStorage; - private final EditorEx myEditor; - private final SoftWrapPainter myPainter; + private final EditorTextRepresentationHelper myTextRepresentationHelper; + private final SoftWrapsStorage myStorage; + private final EditorEx myEditor; + private final SoftWrapPainter myPainter; private int myVisibleAreaWidth; - public DefaultSoftWrapApplianceManager(SoftWrapsStorage storage, EditorEx editor, SoftWrapPainter painter) { + public DefaultSoftWrapApplianceManager(SoftWrapsStorage storage, + EditorEx editor, + SoftWrapPainter painter, + EditorTextRepresentationHelper textRepresentationHelper) + { myStorage = storage; myEditor = editor; myPainter = painter; + myTextRepresentationHelper = textRepresentationHelper; init(editor.getDocument()); } @@ -215,10 +222,11 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager // Find offsets where soft wraps should be applied for the logical line in case of no indent usage. int x = myPainter.getMinDrawingWidth(SoftWrapDrawingType.BEFORE_SOFT_WRAP_LINE_FEED); int prevSoftWrapOffset = start; + CharBuffer buffer = CharBuffer.wrap(text); for (int i = start; i < end; i++) { - int symbolWidth = EditorUtil.textWidth(myEditor, CharBuffer.wrap(text), i, i + 1, fontType, x); + int symbolWidth = myTextRepresentationHelper.textWidth(buffer, i, i + 1, fontType, x); if (x + symbolWidth >= myVisibleAreaWidth) { - int offset = calculateSoftWrapOffset(text, i - 1, prevSoftWrapOffset, end); + int offset = calculateSoftWrapOffset(text, i, prevSoftWrapOffset, end); if (offset >= end || offset <= prevSoftWrapOffset) { // There is no way to insert soft wrap. return result; @@ -272,8 +280,8 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager for (int i = preferred; i > min; i--) { char c = text[i]; - if (i < preferred && WHITE_SPACES.contains(c)) { - return i + 1; + if (WHITE_SPACES.contains(c)) { + return i < preferred ? i + 1 : i; } // Don't wrap on the non-id symbol preceded by another non-id symbol. E.g. consider that we have a statement @@ -281,8 +289,11 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager if (i > min + 1 && !isIdSymbol(c) && !isIdSymbol(text[i - 1])) { continue; } - if ((i < preferred) && SPECIAL_SYMBOLS_TO_WRAP_AFTER.contains(c)) { - return i + 1; + if (SPECIAL_SYMBOLS_TO_WRAP_AFTER.contains(c)) { + if (i < preferred) { + return i + 1; + } + continue; } if (SPECIAL_SYMBOLS_TO_WRAP_BEFORE.contains(c) || WHITE_SPACES.contains(c)) { return i; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapper.java index 87889a12274a..c162cdaafdde 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapper.java @@ -23,6 +23,7 @@ import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.awt.*; import java.util.List; /** @@ -264,7 +265,7 @@ public class SoftWrapDataMapper { int i = CharArrayUtil.shiftBackwardUntil(text, region.getEndOffset() - 1, "\n"); // Process multi-line folding. if (i >= region.getStartOffset()) { - afterFolding.x = myTextRepresentationHelper.textWidth(text, i + 1, region.getEndOffset(), 0); + afterFolding.x = myTextRepresentationHelper.textWidth(text, i + 1, region.getEndOffset(), Font.PLAIN, 0); afterFolding.logicalColumn = myTextRepresentationHelper.toVisualColumnSymbolsNumber(text, i + 1, region.getEndOffset(), 0); afterFolding.softWrapLinesBefore += afterFolding.softWrapLinesCurrent; afterFolding.softWrapLinesCurrent = 0; @@ -274,7 +275,7 @@ public class SoftWrapDataMapper { } // Process single-line folding else { - int width = myTextRepresentationHelper.textWidth(text, region.getStartOffset(), region.getEndOffset(), context.x); + int width = myTextRepresentationHelper.textWidth(text, region.getStartOffset(), region.getEndOffset(), Font.PLAIN, context.x); int logicalColumnInc = myTextRepresentationHelper.toVisualColumnSymbolsNumber( text, region.getStartOffset(), region.getEndOffset(), context.x ); @@ -342,7 +343,7 @@ public class SoftWrapDataMapper { // Update state to the offset that corresponds to the same logical line that was used last time. if (currentLogicalLine == lastUsedLogicalLine) { - int width = myTextRepresentationHelper.textWidth(text, result.offset, newOffset, result.x); + int width = myTextRepresentationHelper.textWidth(text, result.offset, newOffset, Font.PLAIN, result.x); int columnDiff = myTextRepresentationHelper.toVisualColumnSymbolsNumber(text, result.offset, newOffset, result.x); result.x += width; result.logicalColumn += columnDiff; @@ -354,7 +355,7 @@ public class SoftWrapDataMapper { result.logicalLine += lineDiff; result.visualLine += lineDiff; int startLineOffset = document.getLineStartOffset(currentLogicalLine); - int newX = myTextRepresentationHelper.textWidth(text, startLineOffset, newOffset, result.x); + int newX = myTextRepresentationHelper.textWidth(text, startLineOffset, newOffset, Font.PLAIN, result.x); result.visualColumn = myTextRepresentationHelper.toVisualColumnSymbolsNumber(text, startLineOffset, newOffset, 0); result.x = newX; result.logicalColumn = result.visualColumn; diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/DefaultSoftWrapApplianceManagerTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/DefaultSoftWrapApplianceManagerTest.java new file mode 100644 index 000000000000..3baa67b01c81 --- /dev/null +++ b/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/DefaultSoftWrapApplianceManagerTest.java @@ -0,0 +1,196 @@ +/* + * Copyright 2000-2010 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; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.ScrollingModel; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.util.text.StringUtil; +import org.jmock.Expectations; +import org.junit.Test; +import org.junit.Before; +import org.junit.After; +import org.jmock.integration.junit4.JUnit4Mockery; +import org.jmock.Mockery; +import org.jmock.lib.legacy.ClassImposteriser; + +import java.awt.*; +import java.util.Collections; + +/** + * @author Denis Zhdanov + * @since 08/04/2010 + */ +public class DefaultSoftWrapApplianceManagerTest { + + private static final String EDGE_MARKER = ""; + private static final String WRAP_MARKER = ""; + private static final int SOFT_WRAP_DRAWING_SIZE = 11; + + private DefaultSoftWrapApplianceManager myManager; + private Mockery myMockery; + private SoftWrapsStorage myStorage; + private EditorEx myEditor; + private SoftWrapPainter myPainter; + private Document myDocument; + private ScrollingModel myScrollingModel; + + @Before + public void setUp() { + myMockery = new JUnit4Mockery() {{ + setImposteriser(ClassImposteriser.INSTANCE); + }}; + myStorage = myMockery.mock(SoftWrapsStorage.class); + myEditor = myMockery.mock(EditorEx.class); + myPainter = myMockery.mock(SoftWrapPainter.class); + myDocument = myMockery.mock(Document.class); + myScrollingModel = myMockery.mock(ScrollingModel.class); + + myMockery.checking(new Expectations() {{ + // Editor. + allowing(myEditor).isViewer(); will(returnValue(false)); + + // Document. + allowing(myEditor).getDocument(); will(returnValue(myDocument)); + allowing(myDocument).addDocumentListener(with(any(DocumentListener.class))); + allowing(myDocument).getLineNumber(with(any(int.class))); will(returnValue(0)); // Expecting to work only with single lines here. + allowing(myDocument).getLineStartOffset(0); will(returnValue(0)); // Expecting to work only with single lines here. + allowing(myDocument).isWritable(); will(returnValue(true)); + + // Scrolling model. + allowing(myEditor).getScrollingModel(); will(returnValue(myScrollingModel)); + + // Storage. + allowing(myStorage).removeAll(); + + // Soft wrap drawings. + allowing(myPainter).getMinDrawingWidth(with(any(SoftWrapDrawingType.class))); will(returnValue(SOFT_WRAP_DRAWING_SIZE)); + }}); + + myManager = new DefaultSoftWrapApplianceManager(myStorage, myEditor, myPainter, new MockEditorTextRepresentationHelper()); + } + + @After + public void checkExpectations() { + myMockery.assertIsSatisfied(); + } + + @Test + public void commaNotSeparated() { + String document = + "void method(String p1, String p2) {}"; + doTest(document); + } + + @Test + public void wrapOnExceedingWhiteSpace() { + String document = + "void method(String p1, String p2) {}"; + doTest(document); + } + + private void doTest(final String document) { + final Context context = new Context(document); + context.init(); + myMockery.checking(new Expectations() {{ + allowing(myScrollingModel).getVisibleArea(); will(returnValue(new Rectangle(0, 0, context.visualWidth, Integer.MAX_VALUE))); + allowing(myDocument).getLineEndOffset(0); will(returnValue(context.document.length())); + }}); + char[] documentChars = context.document.toCharArray(); + myManager.registerSoftWrapIfNecessary(documentChars, 0, documentChars.length, 0, Font.PLAIN); + } + + private static TextChangeImpl createSoftWrap(int offset, int indent) { + String text = "\n" + StringUtil.join(Collections.nCopies(indent, " "), ""); + return new TextChangeImpl(text, offset, offset); + } + + /** + * Utility class for parsing and initialising test data. + *

+ * Note: this class is line-oriented, i.e. it assumes that target document doesn't contain line feeds. + */ + private class Context { + + private final StringBuilder buffer = new StringBuilder(); + private final String rawDocument; + + private String document; + private int visualWidth; + private int index; + private int wrapIndex; + private int edgeIndex; + + Context(String rawDocument) { + if (rawDocument.contains("\n")) { + throw new IllegalArgumentException( + String.format("Don't expect to test multi-line documents but the one is detected: '%s'", rawDocument) + ); + } + this.rawDocument = rawDocument; + } + + public void init() { + wrapIndex = rawDocument.indexOf(WRAP_MARKER); + edgeIndex = rawDocument.indexOf(EDGE_MARKER); + while (wrapIndex >= 0 || edgeIndex >= 0) { + if (wrapIndex >= 0 && edgeIndex >= 0) { + if (wrapIndex < edgeIndex) { + processWrap(); + } + else { + processEdge(); + } + continue; + } + + if (wrapIndex >= 0) { + processWrap(); + continue; + } + + if (edgeIndex >= 0) { + processEdge(); + continue; + } + break; + } + buffer.append(rawDocument.substring(index)); + assert visualWidth > 0; + document = buffer.toString(); + } + + private void processWrap() { + buffer.append(rawDocument.substring(index, wrapIndex)); + myMockery.checking(new Expectations() {{ + one(myStorage).storeOrReplace(createSoftWrap(buffer.length(), 0)); + }}); + index = wrapIndex + WRAP_MARKER.length(); + wrapIndex = rawDocument.indexOf(WRAP_MARKER, index); + } + + private void processEdge() { + if (visualWidth > 0) { + throw new IllegalArgumentException(String.format("More than one visual edge sign found at the document '%s'", rawDocument)); + } + buffer.append(rawDocument.substring(index, edgeIndex)); + visualWidth = (buffer.length() * MockEditorTextRepresentationHelper.DEFAULT_SPACE_SIZE_IN_PIXELS) + SOFT_WRAP_DRAWING_SIZE + 1; + index = edgeIndex + EDGE_MARKER.length(); + edgeIndex = rawDocument.indexOf(EDGE_MARKER, index); + } + } +} diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/MockEditorTextRepresentationHelper.java b/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/MockEditorTextRepresentationHelper.java new file mode 100644 index 000000000000..1c273ab05379 --- /dev/null +++ b/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/MockEditorTextRepresentationHelper.java @@ -0,0 +1,83 @@ +/* + * Copyright 2000-2010 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; + +import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper; +import org.jetbrains.annotations.NotNull; + +/** +* @author Denis Zhdanov +* @since Aug 5, 2010 9:18:15 AM +*/ +public class MockEditorTextRepresentationHelper implements EditorTextRepresentationHelper { + + public static final int DEFAULT_TAB_SIZE_IN_COLUMNS = 4; + public static final int DEFAULT_SPACE_SIZE_IN_PIXELS = 7; + + private final int mySpaceSizeInPixels; + private final int myTabSizeInColumns; + + public MockEditorTextRepresentationHelper() { + this(DEFAULT_SPACE_SIZE_IN_PIXELS, DEFAULT_TAB_SIZE_IN_COLUMNS); + } + + MockEditorTextRepresentationHelper(int spaceSizeInPixels, int tabSizeInColumns) { + mySpaceSizeInPixels = spaceSizeInPixels; + myTabSizeInColumns = tabSizeInColumns; + } + + public int toVisualColumnSymbolsNumber(char c, int x) { + return toVisualColumnSymbolsNumber(new String(new char[] {c}), 0, 1, x); + } + + @Override + public int toVisualColumnSymbolsNumber(@NotNull CharSequence text, int start, int end, int x) { + int result = 0; + for (int i = start; i < end; i++) { + int width = charWidth(text.charAt(i), x); + result += width / mySpaceSizeInPixels; + if (width % mySpaceSizeInPixels > 0) { + result++; + } + x += width; + } + return result; + } + + @Override + public int textWidth(@NotNull CharSequence text, int start, int end, int fontType, int x) { + int result = 0; + for (int i = start; i < end; i++) { + char c = text.charAt(i); + switch (c) { + case '\n': result = 0; break; + default: result += charWidth(c, result); + } + } + return result; + } + + public int charWidth(char c, int x) { + if (c == '\t') { + int tabWidth = mySpaceSizeInPixels * myTabSizeInColumns; + int tabsNumber = x / tabWidth; + return (tabsNumber + 1) * tabWidth - x; + } + else { + return mySpaceSizeInPixels; + } + } +} diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapperTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapperTest.java index a1dd059acccb..16dc3764f6ef 100644 --- a/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapperTest.java +++ b/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapperTest.java @@ -5,11 +5,9 @@ import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.ex.FoldingModelEx; import com.intellij.openapi.editor.ex.SoftWrapModelEx; -import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import gnu.trove.TIntHashSet; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jmock.Expectations; import org.jmock.Mockery; @@ -21,6 +19,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import java.awt.*; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -207,7 +206,7 @@ public class SoftWrapDataMapperTest { allowing(painter).getMinDrawingWidth(SoftWrapDrawingType.AFTER_SOFT_WRAP); will(returnValue(SOFT_WRAP_DRAWING_WIDTH)); }}); - myRepresentationHelper = new MockEditorTextRepresentationHelper(); + myRepresentationHelper = new MockEditorTextRepresentationHelper(SPACE_SIZE, TAB_SIZE); myAdjuster = new SoftWrapDataMapper(myEditor, myStorage, myRepresentationHelper/*, new MockFontTypeProvider()*/); } @@ -398,7 +397,7 @@ public class SoftWrapDataMapperTest { if (text.charAt(i) == '\n') { break; } - result += myRepresentationHelper.textWidth(text, i, i + 1, 0); + result += myRepresentationHelper.textWidth(text, i, i + 1, Font.PLAIN, 0); } result += SOFT_WRAP_DRAWING_WIDTH; return result; @@ -493,8 +492,6 @@ public class SoftWrapDataMapperTest { // We don't want to perform the check for logical positions that correspond to the folded space because all of them relate to // the same logical position of the folding start. if (!data.foldedSpace && !data.insideTab && !equals(data.logical, actualLogicalByVisual)) { - //TODO den remove - myAdjuster.visualToLogical(data.visual); throw new AssertionError( String.format("Detected unmatched logical position by visual (%s). Expected: '%s', actual: '%s'. Calculation was performed " + "against soft wrap-unaware logical: '%s'", @@ -507,8 +504,6 @@ public class SoftWrapDataMapperTest { // We don't to perform the check for the data that points to soft wrap location here. The reason is that it shares offset // with the first document symbol after soft wrap, hence, examination always fails. if (!data.virtualSpace && !data.insideTab && !equals(data.logical, actualLogicalByOffset)) { - //TODO den remove - myAdjuster.offsetToLogicalPosition(data.offset); throw new AssertionError( String.format("Detected unmatched logical position by offset. Expected: '%s', actual: '%s'. Calculation was performed " + "against offset: '%d' and soft wrap-unaware logical: '%s'", @@ -698,7 +693,7 @@ public class SoftWrapDataMapperTest { } else if (c == '\t') { int tabWidthInColumns = myRepresentationHelper.toVisualColumnSymbolsNumber(c, x); - x += MockEditorTextRepresentationHelper.charWidth(c, x); + x += myRepresentationHelper.charWidth(c, x); // There is a possible case that single tabulation symbols is shown in more than one visual column at IntelliJ editor. // We store data entry only for the first tab column without 'inside tab' flag then. @@ -715,7 +710,7 @@ public class SoftWrapDataMapperTest { } else { logicalColumn++; offset++; - x += MockEditorTextRepresentationHelper.charWidth(c, x); + x += myRepresentationHelper.charWidth(c, x); foldingColumnDiff--; } return; @@ -748,7 +743,7 @@ public class SoftWrapDataMapperTest { visualColumn++; softWrapColumnDiff++; softWrapSymbolsOnCurrentVisualLine++; - x += MockEditorTextRepresentationHelper.charWidth(c, x); + x += myRepresentationHelper.charWidth(c, x); } return; } @@ -769,7 +764,7 @@ public class SoftWrapDataMapperTest { } else if (c == '\t') { int tabWidthInColumns = myRepresentationHelper.toVisualColumnSymbolsNumber(c, x); - x += MockEditorTextRepresentationHelper.charWidth(c, x); + x += myRepresentationHelper.charWidth(c, x); // There is a possible case that single tabulation symbols is shown in more than one visual column at IntelliJ editor. // We store data entry only for the first tab column without 'inside tab' flag then. @@ -789,7 +784,7 @@ public class SoftWrapDataMapperTest { visualColumn++; logicalColumn++; offset++; - x += MockEditorTextRepresentationHelper.charWidth(c, x); + x += myRepresentationHelper.charWidth(c, x); } } @@ -838,51 +833,6 @@ public class SoftWrapDataMapperTest { } } - private static class MockEditorTextRepresentationHelper implements EditorTextRepresentationHelper { - - public int toVisualColumnSymbolsNumber(char c, int x) { - return toVisualColumnSymbolsNumber(new String(new char[] {c}), 0, 1, x); - } - - @Override - public int toVisualColumnSymbolsNumber(@NotNull CharSequence text, int start, int end, int x) { - int result = 0; - for (int i = start; i < end; i++) { - int width = charWidth(text.charAt(i), x); - result += width / SPACE_SIZE; - if (width % SPACE_SIZE > 0) { - result++; - } - x += width; - } - return result; - } - - @Override - public int textWidth(@NotNull CharSequence text, int start, int end, int x) { - int result = 0; - for (int i = start; i < end; i++) { - char c = text.charAt(i); - switch (c) { - case '\n': result = 0; break; - default: result += charWidth(c, result); - } - } - return result; - } - - public static int charWidth(char c, int x) { - if (c == '\t') { - int tabWidth = SPACE_SIZE * TAB_SIZE; - int tabsNumber = x / tabWidth; - return (tabsNumber + 1) * tabWidth - x; - } - else { - return SPACE_SIZE; - } - } - } - //private static class MockFontTypeProvider implements SoftWrapDataMapper.FontTypeProvider { // @Override // public void init(int start) {