mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
folding model implementation cleanup
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -33,11 +33,19 @@ public interface FoldingModel {
|
||||
* @param startOffset the start offset of the region to fold.
|
||||
* @param endOffset the end offset of the region to fold.
|
||||
* @param placeholderText the text to display instead of the region contents when the region is folded.
|
||||
* @return the fold region, or null if folding is currently disabled.
|
||||
* @return the fold region, or <code>null</code> if folding is currently disabled or corresponding region cannot be added (e.g. if it
|
||||
* intersects with another existing region)
|
||||
*/
|
||||
@Nullable
|
||||
FoldRegion addFoldRegion(int startOffset, int endOffset, @NotNull String placeholderText);
|
||||
|
||||
/**
|
||||
* Tries to add given region to the folding model. This method must be called
|
||||
* from the <code>Runnable</code> passed to {@link #runBatchFoldingOperation(Runnable)}.
|
||||
*
|
||||
* @return <code>true</code>, if region was added successfully, <code>false</code> if the region cannot be added, e.g. if it
|
||||
* intersects with another existing region
|
||||
*/
|
||||
boolean addFoldRegion(@NotNull FoldRegion region);
|
||||
|
||||
/**
|
||||
@@ -57,13 +65,22 @@ public interface FoldingModel {
|
||||
FoldRegion[] getAllFoldRegions();
|
||||
|
||||
/**
|
||||
* Checks if the specified offset in the document belongs to a folded region.
|
||||
* Checks if the specified offset in the document belongs to a folded region. The region must contain given offset or be located right
|
||||
* after given offset, i.e. the following condition must hold: foldStartOffset <= offset < foldEndOffset.
|
||||
*
|
||||
* @param offset the offset to check.
|
||||
* @return true if the offset belongs to a folded region, false otherwise.
|
||||
*
|
||||
* @see #getCollapsedRegionAtOffset(int)
|
||||
*/
|
||||
boolean isOffsetCollapsed(int offset);
|
||||
|
||||
/**
|
||||
* Returns collapsed folded region at a given offset or <code>null</code> if there's no such region. Returned region will satisfy the
|
||||
* following condition: region.getStartOffset() <= offset < region.getEndOffset()
|
||||
*
|
||||
* @see #isOffsetCollapsed(int)
|
||||
*/
|
||||
@Nullable
|
||||
FoldRegion getCollapsedRegionAtOffset(int offset);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.
|
||||
@@ -40,7 +40,11 @@ abstract class FoldRegionsTree {
|
||||
private int[] myCachedStartOffsets;
|
||||
private int[] myCachedFoldedLines;
|
||||
int myCachedLastIndex = -1;
|
||||
private ArrayList<FoldRegion> myRegions = ContainerUtil.newArrayList(); //sorted in tree left-to-right topdown traversal order
|
||||
|
||||
//sorted using RangeMarker.BY_START_OFFSET comparator
|
||||
//i.e., first by start offset, then, if start offsets are equal, by end offset
|
||||
private ArrayList<FoldRegion> myRegions = ContainerUtil.newArrayList();
|
||||
|
||||
private static final Comparator<FoldRegion> BY_END_OFFSET = new Comparator<FoldRegion>() {
|
||||
@Override
|
||||
public int compare(FoldRegion r1, FoldRegion r2) {
|
||||
@@ -89,13 +93,15 @@ abstract class FoldRegionsTree {
|
||||
}
|
||||
|
||||
allValid.add(region);
|
||||
|
||||
|
||||
if (!region.isExpanded()) {
|
||||
removeRegionsWithSameStartOffset(visible, region);
|
||||
removeRegionsWithSameStartOffset(topLevels, region);
|
||||
}
|
||||
|
||||
if (currentCollapsed == null || !contains(currentCollapsed, region)) {
|
||||
visible.add(region);
|
||||
}
|
||||
|
||||
if (!region.isExpanded()) {
|
||||
if (currentCollapsed == null || currentCollapsed.getEndOffset() < region.getStartOffset()) {
|
||||
if (!region.isExpanded()) {
|
||||
currentCollapsed = region;
|
||||
topLevels.add(region);
|
||||
}
|
||||
@@ -115,6 +121,17 @@ abstract class FoldRegionsTree {
|
||||
updateCachedOffsets();
|
||||
}
|
||||
|
||||
private static void removeRegionsWithSameStartOffset(List<FoldRegion> regions, FoldRegion region) {
|
||||
for (int i = regions.size() - 1; i >= 0 ; i--) {
|
||||
if (regions.get(i).getStartOffset() == region.getStartOffset()) {
|
||||
regions.remove(i);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static FoldRegion[] toFoldArray(@NotNull List<FoldRegion> topLevels) {
|
||||
return topLevels.isEmpty() ? FoldRegion.EMPTY_ARRAY : topLevels.toArray(new FoldRegion[topLevels.size()]);
|
||||
@@ -164,31 +181,25 @@ abstract class FoldRegionsTree {
|
||||
boolean addRegion(FoldRegion range) {
|
||||
// During batchProcessing elements are inserted in ascending order,
|
||||
// binary search find acceptable insertion place first time
|
||||
final boolean canUseCachedValue;
|
||||
if (myCachedLastIndex >= myRegions.size()) {
|
||||
// todo this happens after removeRegion()... myCachedListIndex must die!
|
||||
canUseCachedValue = false;
|
||||
boolean canUseCachedValue = false;
|
||||
if (isBatchFoldingProcessing() && myCachedLastIndex >= 0 && myCachedLastIndex < myRegions.size()) {
|
||||
FoldRegion lastRegion = myRegions.get(myCachedLastIndex);
|
||||
if (RangeMarker.BY_START_OFFSET.compare(lastRegion, range) < 0) {
|
||||
canUseCachedValue = myCachedLastIndex == (myRegions.size() - 1)
|
||||
|| RangeMarker.BY_START_OFFSET.compare(range, myRegions.get(myCachedLastIndex + 1)) <= 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
canUseCachedValue =
|
||||
myCachedLastIndex != -1 && isBatchFoldingProcessing() && myRegions.get(myCachedLastIndex).getStartOffset() <= range.getStartOffset();
|
||||
}
|
||||
int fastIndex = canUseCachedValue ? myCachedLastIndex + 1 : Collections.binarySearch(myRegions, range, RangeMarker.BY_START_OFFSET);
|
||||
if (fastIndex < 0) fastIndex = -fastIndex - 1;
|
||||
|
||||
// There is a possible case that given range is the first at the current batch iteration. It's also possible that it
|
||||
// range with the same bounds is already registered (e.g. particular range is registered during 'build initial fold regions' phase
|
||||
// and given range has the same offsets but different 'expanded' status.
|
||||
// We explicitly check for such situation, remove existing region and add the given one instead.
|
||||
if (fastIndex < myRegions.size()) {
|
||||
FoldRegion foldRegion = myRegions.get(fastIndex);
|
||||
int index = canUseCachedValue ? myCachedLastIndex + 1 : Collections.binarySearch(myRegions, range, RangeMarker.BY_START_OFFSET);
|
||||
if (index < 0) index = -index - 1;
|
||||
|
||||
if (index < myRegions.size()) {
|
||||
FoldRegion foldRegion = myRegions.get(index);
|
||||
if (TextRange.areSegmentsEqual(foldRegion, range)) {
|
||||
removeRegion(foldRegion);
|
||||
return addRegion(range);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = fastIndex - 1; i >=0; --i) {
|
||||
for (int i = index - 1; i >=0; --i) {
|
||||
final FoldRegion region = myRegions.get(i);
|
||||
if (region.getEndOffset() < range.getStartOffset()) break;
|
||||
if (region.isValid() && intersects(region, range)) {
|
||||
@@ -196,28 +207,15 @@ abstract class FoldRegionsTree {
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = fastIndex; i < myRegions.size(); i++) {
|
||||
for (int i = index; i < myRegions.size(); i++) {
|
||||
final FoldRegion region = myRegions.get(i);
|
||||
|
||||
if (range.getStartOffset() < region.getStartOffset() ||
|
||||
range.getStartOffset() == region.getStartOffset() && range.getEndOffset() > region.getEndOffset()) {
|
||||
for (int j = i + 1; j < myRegions.size(); j++) {
|
||||
final FoldRegion next = myRegions.get(j);
|
||||
if (next.getEndOffset() >= range.getEndOffset() && next.isValid()) {
|
||||
if (next.getStartOffset() < range.getStartOffset()) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
myRegions.add(myCachedLastIndex = i, range);
|
||||
return true;
|
||||
if (region.getStartOffset() > range.getEndOffset()) break;
|
||||
if (region.isValid() && intersects(region, range)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
myRegions.add(myCachedLastIndex = myRegions.size(),range);
|
||||
|
||||
myRegions.add(myCachedLastIndex = index,range);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -274,7 +272,7 @@ abstract class FoldRegionsTree {
|
||||
}
|
||||
|
||||
private static boolean contains(FoldRegion outer, FoldRegion inner) {
|
||||
return outer.getStartOffset() < inner.getStartOffset() && outer.getEndOffset() > inner.getStartOffset();
|
||||
return outer.getStartOffset() <= inner.getStartOffset() && outer.getEndOffset() >= inner.getEndOffset();
|
||||
}
|
||||
|
||||
private static boolean intersects(FoldRegion r1, FoldRegion r2) {
|
||||
@@ -282,7 +280,7 @@ abstract class FoldRegionsTree {
|
||||
final int s2 = r2.getStartOffset();
|
||||
final int e1 = r1.getEndOffset();
|
||||
final int e2 = r2.getEndOffset();
|
||||
return s1 == s2 && e1 == e2 || s1 < s2 && s2 < e1 && e1 < e2 || s2 < s1 && s1 < e2 && e2 < e1;
|
||||
return s1 < s2 && s2 < e1 && e1 < e2 || s2 < s1 && s1 < e2 && e2 < e1;
|
||||
}
|
||||
|
||||
static boolean contains(FoldRegion region, int offset) {
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl;
|
||||
import com.intellij.testFramework.LightPlatformTestCase;
|
||||
import com.intellij.testFramework.PlatformTestCase;
|
||||
|
||||
public class FoldingStressTest extends LightPlatformTestCase {
|
||||
|
||||
static {
|
||||
PlatformTestCase.autodetectPlatformPrefix();
|
||||
}
|
||||
|
||||
public void testStressFoldingFromZeroOffset() throws Exception {
|
||||
for (int len = 2; len < 25; len++) {
|
||||
stress(len);
|
||||
}
|
||||
}
|
||||
|
||||
public void testStress8() throws Exception {
|
||||
DocumentImpl doc = new DocumentImpl("0123456789\n123456789\n23456789");
|
||||
Editor editor = EditorFactory.getInstance().createEditor(doc);
|
||||
try {
|
||||
final FoldingModel model = editor.getFoldingModel();
|
||||
model.runBatchFoldingOperation(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
addAndCollapseFoldRegion(model, 0, 8, "/*...*/");
|
||||
addAndCollapseFoldRegion(model, 10, 12, "/*...*/");
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(10, editor.logicalPositionToOffset(new LogicalPosition(0, 10)));
|
||||
|
||||
for (int line = 0; line <= 3; line++) {
|
||||
for (int column = 0; column <= 100; column++) {
|
||||
LogicalPosition log = new LogicalPosition(line, column);
|
||||
editor.logicalToVisualPosition(log);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
EditorFactory.getInstance().releaseEditor(editor);
|
||||
}
|
||||
}
|
||||
|
||||
private static void stress(final int len) {
|
||||
DocumentImpl doc = new DocumentImpl("0123456789\n123456789\n23456789");
|
||||
Editor editor = EditorFactory.getInstance().createEditor(doc);
|
||||
try {
|
||||
final FoldingModel model = editor.getFoldingModel();
|
||||
model.runBatchFoldingOperation(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
addAndCollapseFoldRegion(model, 0, len, "/*...*/");
|
||||
addAndCollapseFoldRegion(model, len + 2, len + 4, "/*...*/");
|
||||
}
|
||||
});
|
||||
|
||||
for (int line = 0; line <= 3; line++) {
|
||||
for (int column = 0; column <= 100; column++) {
|
||||
LogicalPosition log = new LogicalPosition(line, column);
|
||||
editor.logicalToVisualPosition(log);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
EditorFactory.getInstance().releaseEditor(editor);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addAndCollapseFoldRegion(FoldingModel model, int startOffset, int endOffset, String placeHolder) {
|
||||
FoldRegion foldRegion = model.addFoldRegion(startOffset, endOffset, placeHolder);
|
||||
assertNotNull(foldRegion);
|
||||
foldRegion.setExpanded(false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,182 +1,153 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.ex.FoldingModelEx;
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.testFramework.LightPlatformTestCase;
|
||||
import com.intellij.openapi.editor.impl.AbstractEditorTest;
|
||||
import com.intellij.testFramework.PlatformTestCase;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import com.intellij.testFramework.TestFileType;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class FoldingTest extends LightPlatformTestCase {
|
||||
|
||||
public class FoldingTest extends AbstractEditorTest {
|
||||
static {
|
||||
PlatformTestCase.autodetectPlatformPrefix();
|
||||
}
|
||||
|
||||
public void testStressFoldingFromZeroOffset() throws Exception {
|
||||
for (int len = 2; len < 25; len++) {
|
||||
stress(len);
|
||||
}
|
||||
}
|
||||
private FoldingModelEx myModel;
|
||||
|
||||
public void testStress8() throws Exception {
|
||||
DocumentImpl doc = new DocumentImpl("0123456789\n123456789\n23456789");
|
||||
Editor editor = EditorFactory.getInstance().createEditor(doc);
|
||||
try {
|
||||
final FoldingModel model = editor.getFoldingModel();
|
||||
model.runBatchFoldingOperation(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
model.addFoldRegion(0, 8, "/*...*/").setExpanded(false);
|
||||
model.addFoldRegion(10, 12, "/*...*/").setExpanded(false);
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(10, editor.logicalPositionToOffset(new LogicalPosition(0, 10)));
|
||||
|
||||
for (int line = 0; line <= 3; line++) {
|
||||
for (int column = 0; column <= 100; column++) {
|
||||
LogicalPosition log = new LogicalPosition(line, column);
|
||||
editor.logicalToVisualPosition(log);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
EditorFactory.getInstance().releaseEditor(editor);
|
||||
}
|
||||
}
|
||||
|
||||
private static void stress(final int len) {
|
||||
DocumentImpl doc = new DocumentImpl("0123456789\n123456789\n23456789");
|
||||
Editor editor = EditorFactory.getInstance().createEditor(doc);
|
||||
try {
|
||||
final FoldingModel model = editor.getFoldingModel();
|
||||
model.runBatchFoldingOperation(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
model.addFoldRegion(0, len, "/*...*/").setExpanded(false);
|
||||
model.addFoldRegion(len + 2, len + 4, "/*...*/").setExpanded(false);
|
||||
}
|
||||
});
|
||||
|
||||
for (int line = 0; line <= 3; line++) {
|
||||
for (int column = 0; column <= 100; column++) {
|
||||
LogicalPosition log = new LogicalPosition(line, column);
|
||||
editor.logicalToVisualPosition(log);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
EditorFactory.getInstance().releaseEditor(editor);
|
||||
}
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
init("I don't know what you mean by `glory,'\" Alice said" +
|
||||
"Humpty Dumpty smiled contemptuously. \"Of course you don't -- till I tell you. I meant `there's a nice knock-down argument for you!'" +
|
||||
"But glory doesn't mean `a nice knock-down argument,'\" Alice objected." +
|
||||
"When I use a word,\" Humpty Dumpty said, in a rather scornful tone, \"it means just what I choose it to mean -- neither more nor less." +
|
||||
"The question is,\" said Alice, \"whether you can make words mean so many different things." +
|
||||
"The question is,\" said Humpty Dumpty, \"which is to be master -- that's all.",
|
||||
TestFileType.TEXT);
|
||||
myModel = (FoldingModelEx)myEditor.getFoldingModel();
|
||||
}
|
||||
|
||||
public void testCleanupInvalidRegions() {
|
||||
final DocumentImpl doc = new DocumentImpl("foo1\nfoo2\nfoo3\nfoo4");
|
||||
Editor editor = EditorFactory.getInstance().createEditor(doc);
|
||||
final FoldingModel model = editor.getFoldingModel();
|
||||
try {
|
||||
model.runBatchFoldingOperation(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
model.addFoldRegion(0, 4, "/*...*/");
|
||||
model.addFoldRegion(5, 9, "/*...*/");
|
||||
}
|
||||
});
|
||||
assertSize(2, model.getAllFoldRegions());
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doc.deleteString(0, 5);
|
||||
}
|
||||
});
|
||||
assertSize(1, model.getAllFoldRegions());
|
||||
}
|
||||
finally {
|
||||
EditorFactory.getInstance().releaseEditor(editor);
|
||||
}
|
||||
myModel.runBatchFoldingOperation(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myModel.addFoldRegion(0, 4, "/*...*/");
|
||||
myModel.addFoldRegion(5, 9, "/*...*/");
|
||||
}
|
||||
});
|
||||
assertSize(2, myModel.getAllFoldRegions());
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myEditor.getDocument().deleteString(0, 5);
|
||||
}
|
||||
});
|
||||
assertSize(1, myModel.getAllFoldRegions());
|
||||
}
|
||||
|
||||
public void testIntersects () throws Exception {
|
||||
@NonNls DocumentImpl doc = new DocumentImpl("I don't know what you mean by `glory,'\" Alice said" +
|
||||
"Humpty Dumpty smiled contemptuously. \"Of course you don't -- till I tell you. I meant `there's a nice knock-down argument for you!'" +
|
||||
"But glory doesn't mean `a nice knock-down argument,'\" Alice objected." +
|
||||
"When I use a word,\" Humpty Dumpty said, in a rather scornful tone, \"it means just what I choose it to mean -- neither more nor less." +
|
||||
"The question is,\" said Alice, \"whether you can make words mean so many different things." +
|
||||
"The question is,\" said Humpty Dumpty, \"which is to be master -- that's all." );
|
||||
Editor editor = EditorFactory.getInstance().createEditor(doc);
|
||||
try {
|
||||
final FoldingModel model = editor.getFoldingModel();
|
||||
|
||||
model.runBatchFoldingOperation(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
FoldRegion region = model.addFoldRegion(5, 10, ".");
|
||||
assertNotNull(region);
|
||||
region = model.addFoldRegion(7, 11, ".");
|
||||
assertNull(region);
|
||||
region = model.addFoldRegion(20, 30, ".");
|
||||
assertNotNull(region);
|
||||
region = model.addFoldRegion(9, 12, ".");
|
||||
assertNull(region);
|
||||
region = model.addFoldRegion(7, 10, ".");
|
||||
assertNotNull(region);
|
||||
region = model.addFoldRegion(7, 10, ".");
|
||||
assertNull(region);
|
||||
region = model.addFoldRegion(5, 30, ".");
|
||||
assertNotNull(region);
|
||||
}
|
||||
});
|
||||
}
|
||||
finally {
|
||||
EditorFactory.getInstance().releaseEditor(editor);
|
||||
}
|
||||
myModel.runBatchFoldingOperation(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
FoldRegion region = myModel.addFoldRegion(5, 10, ".");
|
||||
assertNotNull(region);
|
||||
region = myModel.addFoldRegion(7, 11, ".");
|
||||
assertNull(region);
|
||||
region = myModel.addFoldRegion(20, 30, ".");
|
||||
assertNotNull(region);
|
||||
region = myModel.addFoldRegion(9, 12, ".");
|
||||
assertNull(region);
|
||||
region = myModel.addFoldRegion(7, 10, ".");
|
||||
assertNotNull(region);
|
||||
region = myModel.addFoldRegion(7, 10, ".");
|
||||
assertNull(region);
|
||||
region = myModel.addFoldRegion(5, 30, ".");
|
||||
assertNotNull(region);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testDuplicateRegions() {
|
||||
StringBuilder text = new StringBuilder();
|
||||
for (int i = 0; i < 450; i++) {
|
||||
text.append('a');
|
||||
}
|
||||
Editor editor = EditorFactory.getInstance().createEditor(new DocumentImpl(text));
|
||||
public void testAddEmptyRegion() {
|
||||
FoldRegion region = null;
|
||||
try {
|
||||
final Ref<Boolean> expandedStatus = new Ref<Boolean>();
|
||||
final int startOffset = 6;
|
||||
final int endOffset = 16;
|
||||
final FoldingModelEx model = (FoldingModelEx)editor.getFoldingModel();
|
||||
model.runBatchFoldingOperation(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
model.addFoldRegion(2, 20, "..");
|
||||
model.addFoldRegion(4, 18, "..");
|
||||
FoldRegion oldRegion = model.addFoldRegion(startOffset, endOffset, "..");
|
||||
assertNotNull(oldRegion);
|
||||
expandedStatus.set(!oldRegion.isExpanded());
|
||||
}
|
||||
});
|
||||
assertEquals(3, model.getAllFoldRegions().length);
|
||||
|
||||
final Ref<FoldRegion> newRegion = new Ref<FoldRegion>();
|
||||
model.runBatchFoldingOperation(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
newRegion.set(model.createFoldRegion(startOffset, endOffset, "..", null, false));
|
||||
assertNotNull(newRegion.get());
|
||||
newRegion.get().setExpanded(expandedStatus.get());
|
||||
boolean additionFlag = model.addFoldRegion(newRegion.get());
|
||||
assertTrue(additionFlag);
|
||||
}
|
||||
});
|
||||
FoldRegion fetched = model.fetchOutermost(startOffset);
|
||||
assertSame(newRegion.get(), fetched);
|
||||
assertEquals(3, model.getAllFoldRegions().length);
|
||||
region = myModel.addFoldRegion(5, 5, "...");
|
||||
}
|
||||
finally {
|
||||
EditorFactory.getInstance().releaseEditor(editor);
|
||||
catch (AssertionError ignored) {
|
||||
}
|
||||
assertNull(region);
|
||||
}
|
||||
|
||||
public void testCollapsedRegionQueries() {
|
||||
addCollapsedFoldRegion(5, 7, "...");
|
||||
FoldRegion[] regions = myModel.getAllFoldRegions();
|
||||
assertEquals(1, regions.length);
|
||||
FoldRegion region = regions[0];
|
||||
assertNotNull(region);
|
||||
|
||||
assertFalse(myModel.isOffsetCollapsed(4));
|
||||
assertTrue(myModel.isOffsetCollapsed(5));
|
||||
assertTrue(myModel.isOffsetCollapsed(6));
|
||||
assertFalse(myModel.isOffsetCollapsed(7));
|
||||
assertFalse(myModel.isOffsetCollapsed(8));
|
||||
|
||||
assertNull(myModel.getCollapsedRegionAtOffset(4));
|
||||
assertSame(region, myModel.getCollapsedRegionAtOffset(5));
|
||||
assertSame(region, myModel.getCollapsedRegionAtOffset(6));
|
||||
assertNull(myModel.getCollapsedRegionAtOffset(7));
|
||||
assertNull(myModel.getCollapsedRegionAtOffset(8));
|
||||
}
|
||||
|
||||
public void testAdjacentRegions() {
|
||||
addCollapsedFoldRegion(5, 7, "AA");
|
||||
addCollapsedFoldRegion(7, 10, "BB");
|
||||
FoldRegion[] regions = myModel.getAllFoldRegions();
|
||||
assertEquals(2, regions.length);
|
||||
FoldRegion region1 = regions[0];
|
||||
assertNotNull(region1);
|
||||
FoldRegion region2 = regions[1];
|
||||
assertNotNull(region2);
|
||||
|
||||
assertFalse(myModel.isOffsetCollapsed(4));
|
||||
assertTrue(myModel.isOffsetCollapsed(5));
|
||||
assertTrue(myModel.isOffsetCollapsed(6));
|
||||
assertTrue(myModel.isOffsetCollapsed(7));
|
||||
assertTrue(myModel.isOffsetCollapsed(8));
|
||||
assertFalse(myModel.isOffsetCollapsed(10));
|
||||
assertFalse(myModel.isOffsetCollapsed(11));
|
||||
|
||||
assertNull(myModel.getCollapsedRegionAtOffset(4));
|
||||
assertSame(region1, myModel.getCollapsedRegionAtOffset(5));
|
||||
assertSame(region1, myModel.getCollapsedRegionAtOffset(6));
|
||||
assertSame(region2, myModel.getCollapsedRegionAtOffset(7));
|
||||
assertSame(region2, myModel.getCollapsedRegionAtOffset(8));
|
||||
assertNull(myModel.getCollapsedRegionAtOffset(10));
|
||||
assertNull(myModel.getCollapsedRegionAtOffset(11));
|
||||
}
|
||||
|
||||
public void testTopLevel() {
|
||||
FoldRegion region = addCollapsedFoldRegion(5, 15, "...");
|
||||
addCollapsedFoldRegion(10, 12, "???");
|
||||
|
||||
FoldRegion[] topLevelRegions = myModel.fetchTopLevel();
|
||||
assertArrayEquals(new FoldRegion[]{region}, topLevelRegions);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user