Add support for multi line insertion + unit tests

This commit is contained in:
Julian Viereck 2011-04-25 13:29:23 +02:00
commit e9f3ba7b56
3 changed files with 118 additions and 15 deletions

View file

@ -905,15 +905,32 @@ var EditSession = function(text, mode) {
// If some new line is added inside of a foldLine, then split
// the fold line up.
var foldLines = this.$foldData;
var foldLine = this.getFoldLine(firstRow);
if (foldLine && foldLine.range.inside(start.row, start.column)) {
var foldLine = foldLine.split(start.row, start.column);
var idx = 0;
if (foldLine) {
var cmp = foldLine.range.compareInside(start.row, start.column)
// Inside of the foldLine range. Need to split stuff up.
if (cmp == 0) {
// TODO: Handle case where inseration is inside of fold!
foldLine = foldLine.split(start.row, start.column);
foldLine.shiftRow(len);
foldLine.addRemoveChars(
lastRow, 0, end.column - start.column);
this.$addFoldLine(foldLine);
} else
// Infront of the foldLine but same row. Need to shift column.
if (cmp == -1) {
foldLine.addRemoveChars(firstRow, 0, end.column - start.column);
foldLine.shiftRow(len);
}
// Nothing to do if the insert is after the foldLine.
idx = foldLines.indexOf(foldLine) + 1;
}
var foldLines = this.$foldData;
for (var i = 0; i < foldLines.length; i++) {
var foldLine = foldLines[i];
for (idx; idx < foldLines.length; idx++) {
var foldLine = foldLines[idx];
if (foldLine.start.row >= firstRow) {
foldLine.shiftRow(len);
}
@ -1418,11 +1435,24 @@ var EditSession = function(text, mode) {
this.sameRow = range.start.row == range.end.row;
}
function FoldLine(fold) {
this.folds = [fold];
this.range = fold.range.clone();
this.start = this.range.start;
this.end = this.range.end;
/**
* Creates a new FoldLine. If the an array is passed in, the folds are
* expected to be sorted already.
*/
function FoldLine(folds) {
if (Array.isArray(folds)) {
var last = folds[folds.length - 1]
this.folds = folds;
this.range = new Range(folds[0].start.row, folds[0].start.column,
last.end.row, last.end.column);
this.start = this.range.start;
this.end = this.range.end;
} else {
this.folds = [folds];
this.range = folds.range.clone();
this.start = this.range.start;
this.end = this.range.end;
}
}
(function() {
@ -1599,8 +1629,29 @@ var EditSession = function(text, mode) {
}
}
}
this.split = function(row, column) {
var fold = this.getNextFoldTo(row, column).fold,
folds = this.folds;
if (!fold) {
return null;
}
var i = folds.indexOf(fold);
var foldBefore = folds[i - 1];
this.end.row = foldBefore.end.row;
this.end.column = foldBefore.end.column;
// Remove the folds after row/column and create a new FoldLine
// containing these removed folds.
var folds = folds.splice(i, folds.length - i);
return new FoldLine(folds);
}
}).call(FoldLine.prototype);
FoldLine.prototype.__defineGetter__("rangeDBG", function() {
return this.range + "";
})
this.getFoldAt = function(row, column, side) {
var foldLine = this.getFoldLine(row);
if (foldLine) {
@ -1663,6 +1714,13 @@ var EditSession = function(text, mode) {
return null;
}
this.$addFoldLine = function(foldLine) {
this.$foldData.push(foldLine);
this.$foldData.sort(function(a, b) {
return a.start.row - b.start.row;
});
}
/**
* Adds a new fold.
*/
@ -1707,11 +1765,7 @@ var EditSession = function(text, mode) {
}
if (!added) {
foldLine = new FoldLine(fold);
foldData.push(foldLine);
foldData.sort(function(a, b) {
return a.start.row - b.start.row;
});
this.$addFoldLine(new FoldLine(fold));
}
// TODO: Recalculate wrapData

View file

@ -502,6 +502,45 @@ module.exports = {
assert.range(foldLine.range, 1, 12, 2, 27);
assert.range(folds[0].range, 1, 12, 2, 10);
assert.range(folds[1].range, 2, 22, 2, 27);
},
"test fold multi-line insert": function() {
var session = createFoldTestSession(),
foldLines = session.$foldData;
function insert(row, column, text) {
session.insert({row: row, column: column}, text);
}
var foldLines = session.$foldData, foldLine, fold, folds;
insert(0, 0, "\nfoo");
assert.equal(foldLines.length, 2);
assert.range(foldLines[0].range, 1, 16, 1, 21);
assert.range(foldLines[1].range, 2, 10, 3, 25);
insert(2, 0, "\nbar");
assert.equal(foldLines.length, 2);
assert.range(foldLines[0].range, 1, 16, 1, 21);
assert.range(foldLines[1].range, 3, 13, 4, 25);
insert(3, 10, "\nfoo");
assert.equal(foldLines.length, 2);
assert.range(foldLines[0].range, 1, 16, 1, 21);
assert.range(foldLines[1].range, 4, 6, 5, 25);
insert(5, 10, "\nbar");
assert.equal(foldLines.length, 3);
assert.range(foldLines[0].range, 1, 16, 1, 21);
assert.range(foldLines[1].range, 4, 6, 5, 10);
assert.range(foldLines[2].range, 6, 13, 6, 18);
insert(6, 18, "\nfoo");
assert.equal(foldLines.length, 3);
assert.range(foldLines[0].range, 1, 16, 1, 21);
assert.range(foldLines[1].range, 4, 6, 5, 10);
assert.range(foldLines[2].range, 6, 13, 6, 18);
// TODO: Add test for inseration inside of folds.
}
};

View file

@ -145,6 +145,16 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
this.compareInside = function(row, column) {
if (this.end.row == row && this.end.column == column) {
return 1;
} else if (this.start.row == row && this.start.column == column) {
return -1;
} else {
return this.compare(row, column);
}
}
this.clipRows = function(firstRow, lastRow) {
if (this.end.row > lastRow) {
var end = {