addFold must not throw if new fold is inside the existing one
This commit is contained in:
parent
3412f89007
commit
77dfd0b29c
7 changed files with 106 additions and 37 deletions
|
|
@ -837,6 +837,12 @@ var EditSession = function(text, mode) {
|
||||||
return Math.max(0, Math.min(row, this.doc.getLength()-1));
|
return Math.max(0, Math.min(row, this.doc.getLength()-1));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.$clipColumnToRow = function(row, column) {
|
||||||
|
if (column < 0)
|
||||||
|
return 0;
|
||||||
|
return Math.min(this.doc.getLine(row).length, column);
|
||||||
|
};
|
||||||
|
|
||||||
this.$clipPositionToDocument = function(row, column) {
|
this.$clipPositionToDocument = function(row, column) {
|
||||||
column = Math.max(0, column);
|
column = Math.max(0, column);
|
||||||
|
|
||||||
|
|
@ -859,6 +865,30 @@ var EditSession = function(text, mode) {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.$clipRangeToDocument = function(range) {
|
||||||
|
if (range.start.row < 0) {
|
||||||
|
range.start.row = 0;
|
||||||
|
range.start.column = 0
|
||||||
|
} else {
|
||||||
|
range.start.column = this.$clipColumnToRow(
|
||||||
|
range.start.row,
|
||||||
|
range.start.column
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
var len = this.doc.getLength() - 1;
|
||||||
|
if (range.end.row > len) {
|
||||||
|
range.end.row = len;
|
||||||
|
range.end.column = this.doc.getLine(len).length;
|
||||||
|
} else {
|
||||||
|
range.end.column = this.$clipColumnToRow(
|
||||||
|
range.end.row,
|
||||||
|
range.end.column
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return range;
|
||||||
|
};
|
||||||
|
|
||||||
// WRAPMODE
|
// WRAPMODE
|
||||||
this.$wrapLimit = 80;
|
this.$wrapLimit = 80;
|
||||||
this.$useWrapMode = false;
|
this.$useWrapMode = false;
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,42 @@ var Fold = exports.Fold = function(range, placeholder) {
|
||||||
return fold;
|
return fold;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.addSubFold = function(fold) {
|
||||||
|
if (this.range.isEequal(fold))
|
||||||
|
return this;
|
||||||
|
|
||||||
|
if (!this.range.containsRange(fold))
|
||||||
|
throw "A fold can't intersect already existing fold" + fold.range + this.range;
|
||||||
|
|
||||||
|
var row = fold.range.start.row, column = fold.range.start.column;
|
||||||
|
for (var i = 0, cmp = -1; i < this.subFolds.length; i++) {
|
||||||
|
cmp = this.subFolds[i].range.compare(row, column);
|
||||||
|
if (cmp != 1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var afterStart = this.subFolds[i];
|
||||||
|
|
||||||
|
if (cmp == 0)
|
||||||
|
return afterStart.addSubFold(fold)
|
||||||
|
|
||||||
|
// cmp == -1
|
||||||
|
var row = fold.range.end.row, column = fold.range.end.column;
|
||||||
|
for (var j = i, cmp = -1; j < this.subFolds.length; j++) {
|
||||||
|
cmp = this.subFolds[j].range.compare(row, column);
|
||||||
|
if (cmp != 1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var afterEnd = this.subFolds[j];
|
||||||
|
|
||||||
|
if (cmp == 0)
|
||||||
|
throw "A fold can't intersect already existing fold" + fold.range + this.range;
|
||||||
|
|
||||||
|
var consumedFolds = this.subFolds.splice(i, j - i, fold)
|
||||||
|
fold.setFoldLine(this.foldLine);
|
||||||
|
|
||||||
|
return fold;
|
||||||
|
}
|
||||||
|
|
||||||
}).call(Fold.prototype);
|
}).call(Fold.prototype);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
@ -41,7 +41,7 @@ define(function(require, exports, module) {
|
||||||
var Range = require("../range").Range;
|
var Range = require("../range").Range;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the an array is passed in, the folds are expected to be sorted already.
|
* If an array is passed in, the folds are expected to be sorted already.
|
||||||
*/
|
*/
|
||||||
function FoldLine(foldData, folds) {
|
function FoldLine(foldData, folds) {
|
||||||
this.foldData = foldData;
|
this.foldData = foldData;
|
||||||
|
|
|
||||||
|
|
@ -247,6 +247,8 @@ function Folding() {
|
||||||
else
|
else
|
||||||
fold = new Fold(range, placeholder);
|
fold = new Fold(range, placeholder);
|
||||||
|
|
||||||
|
this.$clipRangeToDocument(fold.range);
|
||||||
|
|
||||||
var startRow = fold.start.row;
|
var startRow = fold.start.row;
|
||||||
var startColumn = fold.start.column;
|
var startColumn = fold.start.column;
|
||||||
var endRow = fold.end.row;
|
var endRow = fold.end.row;
|
||||||
|
|
@ -259,29 +261,18 @@ function Folding() {
|
||||||
if (startRow == endRow && endColumn - startColumn < 2)
|
if (startRow == endRow && endColumn - startColumn < 2)
|
||||||
throw "The range has to be at least 2 characters width";
|
throw "The range has to be at least 2 characters width";
|
||||||
|
|
||||||
var existingFold = this.getFoldAt(startRow, startColumn, 1);
|
var startFold = this.getFoldAt(startRow, startColumn, 1);
|
||||||
|
var endFold = this.getFoldAt(endRow, endColumn, -1);
|
||||||
|
if (startFold && endFold == startFold)
|
||||||
|
return startFold.addSubFold(fold);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
existingFold
|
(startFold && !startFold.range.isStart(startRow, startColumn))
|
||||||
&& existingFold.range.isEnd(endRow, endColumn)
|
|| (endFold && !endFold.range.isEnd(endRow, endColumn))
|
||||||
&& existingFold.range.isStart(startRow, startColumn)
|
|
||||||
) {
|
) {
|
||||||
return fold;
|
throw "A fold can't intersect already existing fold" + fold.range + startFold.range;
|
||||||
}
|
}
|
||||||
|
|
||||||
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";
|
|
||||||
|
|
||||||
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())
|
|
||||||
throw "End of fold is outside of the document.";
|
|
||||||
|
|
||||||
if (endColumn > this.getLine(endRow).length || startColumn > this.getLine(startRow).length)
|
|
||||||
throw "End of fold is outside of the document.";
|
|
||||||
|
|
||||||
// Check if there are folds in the range we create the new fold for.
|
// Check if there are folds in the range we create the new fold for.
|
||||||
var folds = this.getFoldsInRange(fold.range);
|
var folds = this.getFoldsInRange(fold.range);
|
||||||
if (folds.length > 0) {
|
if (folds.length > 0) {
|
||||||
|
|
|
||||||
|
|
@ -930,7 +930,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tryAddFold("foo", new Range(0, 13, 0, 17), true);
|
tryAddFold("foo", new Range(0, 13, 0, 17), false);
|
||||||
tryAddFold("foo", new Range(0, 14, 0, 18), true);
|
tryAddFold("foo", new Range(0, 14, 0, 18), true);
|
||||||
tryAddFold("foo", new Range(0, 13, 0, 18), false);
|
tryAddFold("foo", new Range(0, 13, 0, 18), false);
|
||||||
assert.equal(session.$foldData[0].folds.length, 1);
|
assert.equal(session.$foldData[0].folds.length, 1);
|
||||||
|
|
@ -940,9 +940,9 @@ module.exports = {
|
||||||
assert.equal(session.$foldData[0].folds.length, 2);
|
assert.equal(session.$foldData[0].folds.length, 2);
|
||||||
session.removeFold(fold);
|
session.removeFold(fold);
|
||||||
|
|
||||||
tryAddFold("foo", new Range(0, 18, 0, 22), true);
|
tryAddFold("foo", new Range(0, 18, 0, 22), false);
|
||||||
tryAddFold("foo", new Range(0, 18, 0, 19), true);
|
tryAddFold("foo", new Range(0, 18, 0, 19), true);
|
||||||
tryAddFold("foo", new Range(0, 22, 1, 10), true);
|
tryAddFold("foo", new Range(0, 22, 1, 10), false);
|
||||||
},
|
},
|
||||||
|
|
||||||
"test add subfolds": function() {
|
"test add subfolds": function() {
|
||||||
|
|
@ -972,6 +972,12 @@ module.exports = {
|
||||||
assert.equal(foldData[0].folds.length, 1);
|
assert.equal(foldData[0].folds.length, 1);
|
||||||
assert.equal(foldData[0].folds[0], oldFold);
|
assert.equal(foldData[0].folds[0], oldFold);
|
||||||
assert.equal(fold.subFolds.length, 0);
|
assert.equal(fold.subFolds.length, 0);
|
||||||
|
|
||||||
|
session.unfold(null, true);
|
||||||
|
fold = session.addFold("fold0", new Range(0, 0, 0, 21));
|
||||||
|
session.addFold("fold0", new Range(0, 1, 0, 5));
|
||||||
|
session.addFold("fold0", new Range(0, 6, 0, 8));
|
||||||
|
assert.equal(fold.subFolds.length, 2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,12 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
};
|
};
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
this.isEequal = function(range) {
|
||||||
|
return this.start.row == range.start.row &&
|
||||||
|
this.end.row == range.end.row &&
|
||||||
|
this.start.column == range.start.column &&
|
||||||
|
this.end.column == range.end.column
|
||||||
|
};
|
||||||
|
|
||||||
this.toString = function() {
|
this.toString = function() {
|
||||||
return ("Range: [" + this.start.row + "/" + this.start.column +
|
return ("Range: [" + this.start.row + "/" + this.start.column +
|
||||||
|
|
|
||||||
|
|
@ -264,11 +264,11 @@ var VirtualRenderer = function(container, theme) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$onGutterClick = function(e) {
|
this.$onGutterClick = function(e) {
|
||||||
|
var pageX = event.getDocumentX(e);
|
||||||
var pageY = event.getDocumentY(e);
|
var pageY = event.getDocumentY(e);
|
||||||
var row = this.screenToTextCoordinates(0, pageY).row;
|
|
||||||
|
|
||||||
this._dispatchEvent("gutter" + e.type, {
|
this._dispatchEvent("gutter" + e.type, {
|
||||||
row: row,
|
row: this.screenToTextCoordinates(pageX, pageY).row,
|
||||||
htmlEvent: e
|
htmlEvent: e
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue