IDEA-59306 Soft wrap: Throwable at CaretModelImpl.moveToOffset() on inserting tab in last empty line in editor

1. Corrected soft wraps cache recalculation in order to take into account document position after the last symbol;
2. Corresponding test is added (com.intellij.openapi.editor.impl.softwrap.mapping.SoftWrapApplianceOnDocumentModificationTest.testTypingTabOnLastEmptyLine());
This commit is contained in:
Denis Zhdanov
2010-10-01 14:57:40 +04:00
parent 9af1b4d196
commit e5eae8e5f8
6 changed files with 35 additions and 25 deletions
@@ -1,3 +0,0 @@
abcdefghijklmnopqrstuvwxyz<caret>
123
ABCDEFGHIJKLMNOPQRSTUVWXYZ
@@ -1 +0,0 @@
this is a test string that is expected to end just before right margin<caret>
@@ -251,6 +251,15 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw
case '\t': onTabulation(context); break;
default: onNonLineFeedSymbol(context); break;
}
int documentLength = myEditor.getDocument().getTextLength();
if (documentLength > 0 && context.offset >= documentLength - 1 && context.symbol != '\n') {
// Update information about end position of the last visual line.
CacheEntry cacheEntry = getCacheEntryForVisualLine(context.visualLine);
cacheEntry.endLogicalColumn = context.logicalColumn + context.symbolWidthInColumns - 1; // -1 because the first context's
// column already points to the symbol
cacheEntry.endVisualColumn = context.visualColumn + context.symbolWidthInColumns - 1;
}
}
@Override
@@ -70,17 +70,6 @@ class OffsetToLogicalCalculationStrategy extends AbstractMappingStrategy<Logical
}
return;
}
else if (!cache.isEmpty()) {
CacheEntry lastEntry = cache.get(cache.size() - 1);
if (targetOffset > lastEntry.endOffset) {
LogicalPosition eager = new LogicalPosition(
lastEntry.endLogicalLine + 1, 0, lastEntry.endSoftWrapLinesBefore + lastEntry.endSoftWrapLinesCurrent,
0, 0, lastEntry.endFoldedLines, 0
);
setEagerMatch(eager);
return;
}
}
int i = MappingUtil.getCacheEntryIndexForOffset(targetOffset, myEditor.getDocument(), cache);
setCacheEntry(cache.get(i));
@@ -291,7 +291,7 @@ public class SoftWrapApplianceManager implements FoldingListener, DocumentListen
newX = calculateNewX(context, fontType, contentComponent);
}
if (newX + reservedWidth >= myVisibleAreaWidth) {
if (newX + reservedWidth >= myVisibleAreaWidth && delayedSoftWrap == null) {
logicalLineData.update(i, spaceWidth);
SoftWrap softWrap = registerSoftWrap(
softWrapStartOffset, Math.max(softWrapStartOffset, i - 1),
@@ -17,10 +17,8 @@ package com.intellij.openapi.editor.impl.softwrap.mapping;
import com.intellij.openapi.editor.FoldRegion;
import com.intellij.openapi.editor.FoldingModel;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.editor.VisualPosition;
import com.intellij.openapi.editor.ex.SoftWrapModelEx;
import com.intellij.openapi.editor.impl.FoldRegionImpl;
import com.intellij.openapi.editor.impl.SoftWrapModelImpl;
import com.intellij.testFramework.LightPlatformCodeInsightTestCase;
@@ -31,9 +29,9 @@ import java.io.IOException;
* @author Denis Zhdanov
* @since 09/16/2010
*/
public class SoftWrapApplianceManagerTest extends LightPlatformCodeInsightTestCase {
public class SoftWrapApplianceOnDocumentModificationTest extends LightPlatformCodeInsightTestCase {
private static final String PATH = "/codeInsight/softwrap/";
//private static final String PATH = "/codeInsight/softwrap/";
@Override
protected void tearDown() throws Exception {
@@ -42,7 +40,9 @@ public class SoftWrapApplianceManagerTest extends LightPlatformCodeInsightTestCa
}
public void testSoftWrapAdditionOnTyping() throws Exception {
init(800);
String text =
"this is a test string that is expected to end just before right margin<caret>";
init(800, text);
int offset = myEditor.getDocument().getTextLength() + 1;
assertTrue(getSoftWrapModel().getRegisteredSoftWraps().isEmpty());
@@ -51,7 +51,12 @@ public class SoftWrapApplianceManagerTest extends LightPlatformCodeInsightTestCa
}
public void testLongLineOfIdSymbolsIsNotSoftWrapped() throws Exception {
init(100);
String text =
"abcdefghijklmnopqrstuvwxyz<caret>\n" +
"123\n" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
init(100, text);
assertTrue(getSoftWrapModel().getRegisteredSoftWraps().isEmpty());
type('1');
assertTrue(getSoftWrapModel().getRegisteredSoftWraps().isEmpty());
@@ -130,11 +135,22 @@ public class SoftWrapApplianceManagerTest extends LightPlatformCodeInsightTestCa
assertEquals(new VisualPosition(5, 0), myEditor.getCaretModel().getVisualPosition());
}
private void init(final int visibleWidth) throws Exception {
configureByFile(PATH + getFileName());
initCommon(visibleWidth);
public void testTypingTabOnLastEmptyLine() throws IOException {
String text =
"class Test {\n" +
"}\n" +
"<caret>";
init(300, text);
type('\t');
assertEquals(new VisualPosition(2, 4), myEditor.getCaretModel().getVisualPosition());
}
//private void init(final int visibleWidth) throws Exception {
// configureByFile(PATH + getFileName());
// initCommon(visibleWidth);
//}
private void init(int visibleWidth, String fileText) throws IOException {
configureFromFileText(getFileName(), fileText);
initCommon(visibleWidth);