Add sub folding feature. addFold can take a Fold object now.

This commit is contained in:
Julian Viereck 2011-04-28 20:04:45 +02:00
commit f695c253f5
3 changed files with 74 additions and 7 deletions

View file

@ -495,7 +495,7 @@ exports.launch = function(env) {
exec: function() {
var session = env.editor.session,
range = env.editor.selection.getRange();
session.removeFolds(session.getFoldsInRange(range));
session.expandFolds(session.getFoldsInRange(range));
}
});
};

View file

@ -52,6 +52,7 @@ function Fold(range, placeholder) {
this.end = range.end;
this.sameRow = range.start.row == range.end.row;
this.subFolds = [];
}
Fold.prototype.toString = function() {
@ -223,15 +224,25 @@ function Folding() {
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;
}
// --- Some checking ---
@ -251,10 +262,14 @@ function Folding() {
return fold;
}
if (this.getFoldAt(startRow, startColumn, 1)
|| this.getFoldAt(endRow, endColumn, -1))
{
throw "A fold can't start or end inside of an already existing fold";
fold = this.getFoldAt(startRow, startColumn, 1);
if (fold && !fold.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)) {
throw "A fold can't end inside of an already existing fold";
}
if (endRow >= this.doc.$lines.length) {
@ -268,9 +283,18 @@ function Folding() {
}
// --- Start adding the fold ---
fold = new Fold(range, placeholder);
// 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);
if (folds.length > 0) {
// Remove the folds from fold data.
this.removeFolds(folds);
// Add the removed folds as subfolds on the new fold.
fold.subFolds = folds;
}
// For now we assume that no two folds are created for the same range!
for (var i = 0; i < foldData.length; i++) {
foldLine = foldData[i];
if (endRow == foldLine.start.row) {
@ -375,6 +399,20 @@ function Folding() {
this.$modified = true;
}
this.expandFold = function(fold) {
this.removeFold(fold);
fold.subFolds.forEach(function(fold) {
this.addFold(fold);
}, this);
fold.subFolds = [];
}
this.expandFolds = function(folds) {
folds.forEach(function(fold) {
this.expandFold(fold);
}, this);
}
/**
* Checks if a given documentRow is folded. This is true if there are some
* folded parts such that some parts of the line is still visible.

View file

@ -826,6 +826,35 @@ module.exports = {
tryAddFold("foo", 0, 18, 0, 22, true);
tryAddFold("foo", 0, 18, 0, 19, true);
tryAddFold("foo", 0, 22, 1, 10, true);
},
"test add subfolds": function() {
var session = createFoldTestSession();
var fold, oldFold;
var foldData = session.$foldData;
oldFold = foldData[0].folds[0];
fold = session.addFold("fold0", 0, 10, 0, 21);
assert.equal(foldData[0].folds.length, 1);
assert.equal(fold.subFolds.length, 1);
assert.equal(fold.subFolds[0], oldFold);
session.expandFold(fold);
assert.equal(foldData[0].folds.length, 1);
assert.equal(foldData[0].folds[0], oldFold);
assert.equal(fold.subFolds.length, 0);
fold = session.addFold("fold0", 0, 13, 2, 10);
assert.equal(foldData.length, 1);
assert.equal(fold.subFolds.length, 2);
assert.equal(fold.subFolds[0], oldFold);
session.expandFold(fold);
assert.equal(foldData.length, 2);
assert.equal(foldData[0].folds.length, 1);
assert.equal(foldData[0].folds[0], oldFold);
assert.equal(fold.subFolds.length, 0);
}
};