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));
|
||||
};
|
||||
|
||||
this.$clipColumnToRow = function(row, column) {
|
||||
if (column < 0)
|
||||
return 0;
|
||||
return Math.min(this.doc.getLine(row).length, column);
|
||||
};
|
||||
|
||||
this.$clipPositionToDocument = function(row, 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
|
||||
this.$wrapLimit = 80;
|
||||
this.$useWrapMode = false;
|
||||
|
|
|
|||
|
|
@ -74,6 +74,42 @@ var Fold = exports.Fold = function(range, placeholder) {
|
|||
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);
|
||||
|
||||
});
|
||||
|
|
@ -41,7 +41,7 @@ define(function(require, exports, module) {
|
|||
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) {
|
||||
this.foldData = foldData;
|
||||
|
|
|
|||
|
|
@ -247,6 +247,8 @@ function Folding() {
|
|||
else
|
||||
fold = new Fold(range, placeholder);
|
||||
|
||||
this.$clipRangeToDocument(fold.range);
|
||||
|
||||
var startRow = fold.start.row;
|
||||
var startColumn = fold.start.column;
|
||||
var endRow = fold.end.row;
|
||||
|
|
@ -259,29 +261,18 @@ function Folding() {
|
|||
if (startRow == endRow && endColumn - startColumn < 2)
|
||||
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 (
|
||||
existingFold
|
||||
&& existingFold.range.isEnd(endRow, endColumn)
|
||||
&& existingFold.range.isStart(startRow, startColumn)
|
||||
(startFold && !startFold.range.isStart(startRow, startColumn))
|
||||
|| (endFold && !endFold.range.isEnd(endRow, endColumn))
|
||||
) {
|
||||
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.
|
||||
var folds = this.getFoldsInRange(fold.range);
|
||||
if (folds.length > 0) {
|
||||
|
|
|
|||
|
|
@ -109,10 +109,10 @@ module.exports = {
|
|||
assert.position(session.findMatchingBracket({row: 6, column: 20}), 1, 15);
|
||||
assert.position(session.findMatchingBracket({row: 1, column: 22}), 1, 20);
|
||||
assert.position(session.findMatchingBracket({row: 3, column: 31}), 3, 21);
|
||||
assert.position(session.findMatchingBracket({row: 4, column: 24}), 4, 19);
|
||||
assert.position(session.findMatchingBracket({row: 4, column: 24}), 4, 19);
|
||||
assert.equal(session.findMatchingBracket({row: 0, column: 1}), null);
|
||||
},
|
||||
|
||||
|
||||
"test: find matching closing bracket in JavaScript mode" : function() {
|
||||
var lines = [
|
||||
"function foo() {",
|
||||
|
|
@ -131,7 +131,7 @@ module.exports = {
|
|||
assert.position(session.findMatchingBracket({row: 1, column: 16}), 6, 19);
|
||||
assert.position(session.findMatchingBracket({row: 1, column: 21}), 1, 21);
|
||||
assert.position(session.findMatchingBracket({row: 3, column: 22}), 3, 30);
|
||||
assert.position(session.findMatchingBracket({row: 4, column: 20}), 4, 23);
|
||||
assert.position(session.findMatchingBracket({row: 4, column: 20}), 4, 23);
|
||||
},
|
||||
|
||||
"test: handle unbalanced brackets in JavaScript mode" : function() {
|
||||
|
|
@ -223,7 +223,7 @@ module.exports = {
|
|||
"12\t\t34",
|
||||
"ぁぁa"
|
||||
]);
|
||||
|
||||
|
||||
assert.equal(session.getScreenLastRowColumn(0), 4);
|
||||
assert.equal(session.getScreenLastRowColumn(1), 10);
|
||||
assert.equal(session.getScreenLastRowColumn(2), 5);
|
||||
|
|
@ -267,13 +267,13 @@ module.exports = {
|
|||
"12\t\t34",
|
||||
"ぁぁa"
|
||||
]);
|
||||
|
||||
|
||||
assert.position(session.documentToScreenPosition(0, 3), 0, 3);
|
||||
assert.position(session.documentToScreenPosition(1, 3), 1, 4);
|
||||
assert.position(session.documentToScreenPosition(1, 4), 1, 8);
|
||||
assert.position(session.documentToScreenPosition(2, 2), 2, 4);
|
||||
},
|
||||
|
||||
|
||||
"test: documentToScreen with soft wrap": function() {
|
||||
var session = new EditSession(["foo bar foo bar"]);
|
||||
session.setUseWrapMode(true);
|
||||
|
|
@ -283,7 +283,7 @@ module.exports = {
|
|||
assert.position(session.documentToScreenPosition(0, 11), 0, 11);
|
||||
assert.position(session.documentToScreenPosition(0, 12), 1, 0);
|
||||
},
|
||||
|
||||
|
||||
"test: documentToScreen with soft wrap and multibyte characters": function() {
|
||||
|
||||
session = new EditSession(["ぁぁa"]);
|
||||
|
|
@ -298,7 +298,7 @@ module.exports = {
|
|||
|
||||
"test: documentToScreen should clip position to the document boundaries": function() {
|
||||
var session = new EditSession("foo bar\njuhu kinners");
|
||||
|
||||
|
||||
assert.position(session.documentToScreenPosition(-1, 4), 0, 0);
|
||||
assert.position(session.documentToScreenPosition(3, 0), 1, 12);
|
||||
},
|
||||
|
|
@ -340,7 +340,7 @@ module.exports = {
|
|||
assert.position(session.screenToDocumentPosition(0, 12), 0, 11);
|
||||
assert.position(session.screenToDocumentPosition(0, 20), 0, 11);
|
||||
},
|
||||
|
||||
|
||||
"test: screenToDocument with soft wrap and multi byte characters": function() {
|
||||
session = new EditSession(["ぁ a"]);
|
||||
session.setUseWrapMode(true);
|
||||
|
|
@ -352,10 +352,10 @@ module.exports = {
|
|||
assert.position(session.screenToDocumentPosition(0, 4), 0, 3);
|
||||
assert.position(session.screenToDocumentPosition(0, 5), 0, 3);
|
||||
},
|
||||
|
||||
|
||||
"test: screenToDocument should clip position to the document boundaries": function() {
|
||||
var session = new EditSession("foo bar\njuhu kinners");
|
||||
|
||||
|
||||
assert.position(session.screenToDocumentPosition(-1, 4), 0, 0);
|
||||
assert.position(session.screenToDocumentPosition(0, -1), 0, 0);
|
||||
assert.position(session.screenToDocumentPosition(0, 30), 0, 7);
|
||||
|
|
@ -649,7 +649,7 @@ module.exports = {
|
|||
var session = createFoldTestSession();
|
||||
var undoManager = session.getUndoManager();
|
||||
var foldLines = session.$foldData;
|
||||
|
||||
|
||||
function insert(row, column, text) {
|
||||
session.insert({row: row, column: column}, text);
|
||||
|
||||
|
|
@ -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, 13, 0, 18), false);
|
||||
assert.equal(session.$foldData[0].folds.length, 1);
|
||||
|
|
@ -940,9 +940,9 @@ module.exports = {
|
|||
assert.equal(session.$foldData[0].folds.length, 2);
|
||||
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, 22, 1, 10), true);
|
||||
tryAddFold("foo", new Range(0, 22, 1, 10), false);
|
||||
},
|
||||
|
||||
"test add subfolds": function() {
|
||||
|
|
@ -972,6 +972,12 @@ module.exports = {
|
|||
assert.equal(foldData[0].folds.length, 1);
|
||||
assert.equal(foldData[0].folds[0], oldFold);
|
||||
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() {
|
||||
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() {
|
||||
return ("Range: [" + this.start.row + "/" + this.start.column +
|
||||
|
|
|
|||
|
|
@ -264,11 +264,11 @@ var VirtualRenderer = function(container, theme) {
|
|||
};
|
||||
|
||||
this.$onGutterClick = function(e) {
|
||||
var pageX = event.getDocumentX(e);
|
||||
var pageY = event.getDocumentY(e);
|
||||
var row = this.screenToTextCoordinates(0, pageY).row;
|
||||
|
||||
this._dispatchEvent("gutter" + e.type, {
|
||||
row: row,
|
||||
row: this.screenToTextCoordinates(pageX, pageY).row,
|
||||
htmlEvent: e
|
||||
});
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue