make addFold arguments less flexible and do some

cleanups in the folding code
This commit is contained in:
Fabian Jakobs 2011-07-25 12:00:19 +02:00
commit 44b8d656f2
3 changed files with 118 additions and 151 deletions

View file

@ -657,11 +657,11 @@ exports.launch = function(env) {
var fold = session.getFoldAt(range.start.row, range.start.column);
var column;
if(fold) {
if (fold) {
session.expandFold(fold);
selection.setSelectionRange(fold.range)
} else if(br) {
if(range.compare(br.row,br.column) == 1)
} else if (br) {
if (range.compare(br.row, br.column) == 1)
range.end = br;
else
range.start = br;
@ -686,7 +686,7 @@ exports.launch = function(env) {
} else {
addFold = true;
}
if(addFold) {
if (addFold) {
var placeHolder = session.getTextRange(range);
if(placeHolder.length < 3)
return;

View file

@ -50,25 +50,22 @@ function Folding() {
*/
this.getFoldAt = function(row, column, side) {
var foldLine = this.getFoldLine(row);
if (foldLine) {
var folds = foldLine.folds,
fold;
for (var i = 0; i < folds.length; i++) {
fold = folds[i];
if (fold.range.contains(row, column)) {
if (side == 1 && fold.range.isEnd(row, column)) {
continue;
} else if (side == -1 && fold.range.isStart(row, column)) {
continue;
}
return fold;
}
}
} else {
if (!foldLine)
return null;
var folds = foldLine.folds;
for (var i = 0; i < folds.length; i++) {
var fold = folds[i];
if (fold.range.contains(row, column)) {
if (side == 1 && fold.range.isEnd(row, column)) {
continue;
} else if (side == -1 && fold.range.isStart(row, column)) {
continue;
}
return fold;
}
}
}
};
/**
* Returns all folds in the given range. Note, that this will return folds
@ -76,33 +73,30 @@ function Folding() {
*/
this.getFoldsInRange = function(range) {
range = range.clone();
var start = range.start,
end = range.end;
var foldLines = this.$foldData,
folds,
fold;
var cmp,
foundFolds = [];
var start = range.start;
var end = range.end;
var foldLines = this.$foldData;
var foundFolds = [];
start.column += 1;
end.column -= 1;
for (var i = 0; i < foldLines.length; i++) {
cmp = foldLines[i].range.compareRange(range);
// Range is before foldLine. No intersection. This means,
// there might be other foldLines that intersect.
var cmp = foldLines[i].range.compareRange(range);
if (cmp == 2) {
// Range is before foldLine. No intersection. This means,
// there might be other foldLines that intersect.
continue;
} else
// Range is after foldLine. There can't be any other foldLines then,
// so let's give up.
if (cmp == -2) {
}
else if (cmp == -2) {
// Range is after foldLine. There can't be any other foldLines then,
// so let's give up.
break;
}
folds = foldLines[i].folds;
var folds = foldLines[i].folds;
for (var j = 0; j < folds.length; j++) {
fold = folds[j];
var fold = folds[j];
cmp = fold.range.compareRange(range);
if (cmp == -2) {
break;
@ -138,46 +132,44 @@ function Folding() {
*/
this.getFoldStringAt = function(row, column, trim, foldLine) {
var foldLine = foldLine || this.getFoldLine(row);
if (!foldLine) {
if (!foldLine)
return null;
} else {
var fold, lastFold, cmp, str;
lastFold = {
end: { column: 0 }
};
// TODO: Refactor to use getNextFoldTo function.
for (var i = 0; i < foldLine.folds.length; i++) {
fold = foldLine.folds[i];
cmp = fold.range.compareEnd(row, column);
if (cmp == -1) {
str = this.getLine(fold.start.row).
substring(lastFold.end.column, fold.start.column);
break;
} else if (cmp == 0) {
return null;
}
lastFold = fold;
var lastFold = {
end: { column: 0 }
};
// TODO: Refactor to use getNextFoldTo function.
for (var i = 0; i < foldLine.folds.length; i++) {
var fold = foldLine.folds[i];
var cmp = fold.range.compareEnd(row, column);
if (cmp == -1) {
var str = this
.getLine(fold.start.row)
.substring(lastFold.end.column, fold.start.column);
break;
}
if (!str) {
str = this.getLine(fold.start.row).
substring(lastFold.end.column);
}
if (trim == -1) {
return str.substring(0, column - lastFold.end.column);
} else if (trim == 1) {
return str.substring(column - lastFold.end.column)
} else {
return str;
else if (cmp == 0) {
return null;
}
lastFold = fold;
}
if (!str)
str = this.getLine(fold.start.row).substring(lastFold.end.column);
if (trim == -1)
return str.substring(0, column - lastFold.end.column);
else if (trim == 1)
return str.substring(column - lastFold.end.column)
else
return str;
}
this.getFoldLine = function(docRow, startFoldLine) {
var foldData = this.$foldData;
var i = 0;
if(startFoldLine)
if (startFoldLine)
i = foldData.indexOf(startFoldLine);
if(i == -1)
if (i == -1)
i = 0;
for (i; i < foldData.length; i++) {
var foldLine = foldData[i];
@ -194,9 +186,9 @@ function Folding() {
this.getNextFold = function(docRow, startFoldLine) {
var foldData = this.$foldData, ans;
var i = 0;
if(startFoldLine)
if (startFoldLine)
i = foldData.indexOf(startFoldLine);
if(i == -1)
if (i == -1)
i = 0;
for (i; i < foldData.length; i++) {
var foldLine = foldData[i];
@ -213,7 +205,7 @@ function Folding() {
var foldLine = foldData[i],
end = foldLine.end.row,
start = foldLine.start.row;
if(end >= last) {
if (end >= last) {
if(start < last) {
if(start >= first)
rowCount -= last-start;
@ -246,76 +238,55 @@ function Folding() {
* The new created Fold object or an existing fold object in case the
* passed in range fits an existing fold exactly.
*/
this.addFold = function(placeholder, startRow, startColumn, endRow, endColumn) {
var range;
this.addFold = function(placeholder, range) {
var foldData = this.$foldData;
var foldRow = null;
var foldLine;
var fold;
var argsFold;
var folds;
var added = false;
if (placeholder instanceof Fold) {
argsFold = placeholder;
startRow = argsFold.range;
placeholder = argsFold.placeholder;
}
// Normalize parameters.
if (!(startRow instanceof Range)) {
range = new Range(startRow, startColumn, endRow, endColumn);
} else {
range = startRow;
startRow = range.start.row;
startColumn = range.start.column;
endRow = range.end.row;
endColumn = range.end.column;
}
if (placeholder instanceof Fold)
var fold = placeholder;
else
fold = new Fold(range, placeholder);
var startRow = fold.start.row;
var startColumn = fold.start.column;
var endRow = fold.end.row;
var endColumn = fold.end.column;
// --- Some checking ---
if (placeholder.length < 2) {
if (fold.placeholder.length < 2)
throw "Placeholder has to be at least 2 characters";
}
if (startRow == endRow && endColumn - startColumn < 2) {
if (startRow == endRow && endColumn - startColumn < 2)
throw "The range has to be at least 2 characters width";
}
fold = this.getFoldAt(startRow, startColumn, 1);
if (fold
&& fold.range.isEnd(endRow, endColumn)
&& fold.range.isStart(startRow, startColumn))
{
var existingFold = this.getFoldAt(startRow, startColumn, 1);
if (
existingFold
&& existingFold.range.isEnd(endRow, endColumn)
&& existingFold.range.isStart(startRow, startColumn)
) {
return fold;
}
fold = this.getFoldAt(startRow, startColumn, 1);
if (fold && !fold.range.isStart(startRow, startColumn)) {
existingFold = this.getFoldAt(startRow, startColumn, 1);
if (existingFold && !existingFold.range.isStart(startRow, startColumn))
throw "A fold can't start inside of an already existing fold";
}
fold = this.getFoldAt(endRow, endColumn, -1);
if (fold && !fold.range.isEnd(endRow, endColumn)) {
existingFold = this.getFoldAt(endRow, endColumn, -1);
if (existingFold && !existingFold.range.isEnd(endRow, endColumn))
throw "A fold can't end inside of an already existing fold";
}
if (endRow >= this.doc.getLength()) {
if (endRow >= this.doc.getLength())
throw "End of fold is outside of the document.";
}
if (endColumn > this.getLine(endRow).length
|| startColumn > this.getLine(startRow).length)
{
if (endColumn > this.getLine(endRow).length || startColumn > this.getLine(startRow).length)
throw "End of fold is outside of the document.";
}
// --- Start adding the fold ---
// Use the passed in fold or create a new one.
fold = argsFold || new Fold(range, placeholder);
// Check if there are folds in the range we create the new fold for.
folds = this.getFoldsInRange(range);
folds = this.getFoldsInRange(fold.range);
if (folds.length > 0) {
// Remove the folds from fold data.
this.removeFolds(folds);
@ -329,7 +300,8 @@ function Folding() {
foldLine.addFold(fold);
added = true;
break;
} else if (startRow == foldLine.end.row) {
}
else if (startRow == foldLine.end.row) {
foldLine.addFold(fold);
added = true;
if (!fold.sameRow) {
@ -342,18 +314,17 @@ function Folding() {
}
}
break;
} else if (endRow <= foldLine.start.row) {
}
else if (endRow <= foldLine.start.row) {
break;
}
}
if (!added) {
if (!added)
foldLine = this.$addFoldLine(new FoldLine(this.$foldData, fold));
}
if (this.$useWrapMode) {
if (this.$useWrapMode)
this.$updateWrapData(foldLine.start.row, foldLine.start.row);
}
// Notify that fold data has changed.
this.$modified = true;

View file

@ -768,45 +768,45 @@ module.exports = {
// Adding a fold. The split position is inside of the fold. As placeholder
// are not splitable, the split should be before the split.
session.addFold("woot", 0, 4, 0, 15);
session.addFold("woot", new Range(0, 4, 0, 15));
assertWrap([4], [8], [8]);
// Remove the fold again which should reset the wrapData.
removeFoldAssertWrap(0, 4, [8], [8], [8]);
session.addFold("woot", 0, 6, 0, 9);
session.addFold("woot", new Range(0, 6, 0, 9));
assertWrap([6, 13], [8], [8]);
removeFoldAssertWrap(0, 6, [8], [8], [8]);
// The fold fits into the wrap limit - no split expected.
session.addFold("woot", 0, 3, 0, 15);
session.addFold("woot", new Range(0, 3, 0, 15));
assertWrap([], [8], [8]);
removeFoldAssertWrap(0, 4, [8], [8], [8]);
// Fold after split position should be all fine.
session.addFold("woot", 0, 8, 0, 15);
session.addFold("woot", new Range(0, 8, 0, 15));
assertWrap([8], [8], [8]);
removeFoldAssertWrap(0, 8, [8], [8], [8]);
// Fold's placeholder is far too long for wrapSplit.
session.addFold("woot0123456789", 0, 8, 0, 15);
session.addFold("woot0123456789", new Range(0, 8, 0, 15));
assertWrap([8], [8], [8]);
removeFoldAssertWrap(0, 8, [8], [8], [8]);
// Fold's placeholder is far too long for wrapSplit
// + content at the end of the line
session.addFold("woot0123456789", 0, 6, 0, 8);
session.addFold("woot0123456789", new Range(0, 6, 0, 8));
assertWrap([6, 20], [8], [8]);
removeFoldAssertWrap(0, 8, [8], [8], [8]);
session.addFold("woot0123456789", 0, 6, 0, 8);
session.addFold("woot0123456789", 0, 8, 0, 10);
session.addFold("woot0123456789", new Range(0, 6, 0, 8));
session.addFold("woot0123456789", new Range(0, 8, 0, 10));
assertWrap([6, 20, 34], [8], [8]);
session.removeFold(session.getFoldAt(0, 7));
removeFoldAssertWrap(0, 8, [8], [8], [8]);
session.addFold("woot0123456789", 0, 7, 0, 9);
session.addFold("woot0123456789", 0, 13, 0, 15);
session.addFold("woot0123456789", new Range(0, 7, 0, 9));
session.addFold("woot0123456789", new Range(0, 13, 0, 15));
assertWrap([7, 21, 25], [8], [8]);
session.removeFold(session.getFoldAt(0, 7));
removeFoldAssertWrap(0, 14, [8], [8], [8]);
@ -815,15 +815,15 @@ module.exports = {
// Add a fold over two lines. Note, that the wrapData[1] stays the
// same. This is an implementation detail and expected behavior.
session.addFold("woot", 0, 8, 1, 15);
session.addFold("woot", new Range(0, 8, 1, 15));
assertWrap([8], [8 /* See comments */], [8]);
removeFoldAssertWrap(0, 8, [8], [8], [8]);
session.addFold("woot", 0, 9, 1, 11);
session.addFold("woot", new Range(0, 9, 1, 11));
assertWrap([8, 14], [8 /* See comments */], [8]);
removeFoldAssertWrap(0, 9, [8], [8], [8]);
session.addFold("woot", 0, 9, 1, 15);
session.addFold("woot", new Range(0, 9, 1, 15));
assertWrap([8], [8 /* See comments */], [8]);
removeFoldAssertWrap(0, 9, [8], [8], [8]);
@ -834,14 +834,10 @@ module.exports = {
var session = createFoldTestSession();
var fold;
function tryAddFold(
placeholder,
startRow, startColumn, endRow, endColumn, shouldFail)
{
function tryAddFold(placeholder, range, shouldFail) {
var fail = false;
try {
fold = session.addFold(placeholder,
startRow, startColumn, endRow, endColumn);
fold = session.addFold(placeholder, range);
} catch (e) {
fail = true;
}
@ -850,19 +846,19 @@ module.exports = {
}
}
tryAddFold("foo", 0, 13, 0, 17, true);
tryAddFold("foo", 0, 14, 0, 18, true);
tryAddFold("foo", 0, 13, 0, 18, false);
tryAddFold("foo", new Range(0, 13, 0, 17), true);
tryAddFold("foo", new Range(0, 14, 0, 18), true);
tryAddFold("foo", new Range(0, 13, 0, 18), false);
assert.equal(session.$foldData[0].folds.length, 1);
tryAddFold("f", 0, 13, 0, 18, true);
tryAddFold("foo", 0, 18, 0, 21, false);
tryAddFold("f", new Range(0, 13, 0, 18), true);
tryAddFold("foo", new Range(0, 18, 0, 21), false);
assert.equal(session.$foldData[0].folds.length, 2);
session.removeFold(fold);
tryAddFold("foo", 0, 18, 0, 22, true);
tryAddFold("foo", 0, 18, 0, 19, true);
tryAddFold("foo", 0, 22, 1, 10, true);
tryAddFold("foo", new Range(0, 18, 0, 22), true);
tryAddFold("foo", new Range(0, 18, 0, 19), true);
tryAddFold("foo", new Range(0, 22, 1, 10), true);
},
"test add subfolds": function() {
@ -872,7 +868,7 @@ module.exports = {
oldFold = foldData[0].folds[0];
fold = session.addFold("fold0", 0, 10, 0, 21);
fold = session.addFold("fold0", new Range(0, 10, 0, 21));
assert.equal(foldData[0].folds.length, 1);
assert.equal(fold.subFolds.length, 1);
assert.equal(fold.subFolds[0], oldFold);
@ -882,7 +878,7 @@ module.exports = {
assert.equal(foldData[0].folds[0], oldFold);
assert.equal(fold.subFolds.length, 0);
fold = session.addFold("fold0", 0, 13, 2, 10);
fold = session.addFold("fold0", new Range(0, 13, 2, 10));
assert.equal(foldData.length, 1);
assert.equal(fold.subFolds.length, 2);
assert.equal(fold.subFolds[0], oldFold);