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) {
|
||||||
|
|
|
||||||
|
|
@ -109,10 +109,10 @@ module.exports = {
|
||||||
assert.position(session.findMatchingBracket({row: 6, column: 20}), 1, 15);
|
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: 1, column: 22}), 1, 20);
|
||||||
assert.position(session.findMatchingBracket({row: 3, column: 31}), 3, 21);
|
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);
|
assert.equal(session.findMatchingBracket({row: 0, column: 1}), null);
|
||||||
},
|
},
|
||||||
|
|
||||||
"test: find matching closing bracket in JavaScript mode" : function() {
|
"test: find matching closing bracket in JavaScript mode" : function() {
|
||||||
var lines = [
|
var lines = [
|
||||||
"function foo() {",
|
"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: 16}), 6, 19);
|
||||||
assert.position(session.findMatchingBracket({row: 1, column: 21}), 1, 21);
|
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: 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() {
|
"test: handle unbalanced brackets in JavaScript mode" : function() {
|
||||||
|
|
@ -223,7 +223,7 @@ module.exports = {
|
||||||
"12\t\t34",
|
"12\t\t34",
|
||||||
"ぁぁa"
|
"ぁぁa"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert.equal(session.getScreenLastRowColumn(0), 4);
|
assert.equal(session.getScreenLastRowColumn(0), 4);
|
||||||
assert.equal(session.getScreenLastRowColumn(1), 10);
|
assert.equal(session.getScreenLastRowColumn(1), 10);
|
||||||
assert.equal(session.getScreenLastRowColumn(2), 5);
|
assert.equal(session.getScreenLastRowColumn(2), 5);
|
||||||
|
|
@ -267,13 +267,13 @@ module.exports = {
|
||||||
"12\t\t34",
|
"12\t\t34",
|
||||||
"ぁぁa"
|
"ぁぁa"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert.position(session.documentToScreenPosition(0, 3), 0, 3);
|
assert.position(session.documentToScreenPosition(0, 3), 0, 3);
|
||||||
assert.position(session.documentToScreenPosition(1, 3), 1, 4);
|
assert.position(session.documentToScreenPosition(1, 3), 1, 4);
|
||||||
assert.position(session.documentToScreenPosition(1, 4), 1, 8);
|
assert.position(session.documentToScreenPosition(1, 4), 1, 8);
|
||||||
assert.position(session.documentToScreenPosition(2, 2), 2, 4);
|
assert.position(session.documentToScreenPosition(2, 2), 2, 4);
|
||||||
},
|
},
|
||||||
|
|
||||||
"test: documentToScreen with soft wrap": function() {
|
"test: documentToScreen with soft wrap": function() {
|
||||||
var session = new EditSession(["foo bar foo bar"]);
|
var session = new EditSession(["foo bar foo bar"]);
|
||||||
session.setUseWrapMode(true);
|
session.setUseWrapMode(true);
|
||||||
|
|
@ -283,7 +283,7 @@ module.exports = {
|
||||||
assert.position(session.documentToScreenPosition(0, 11), 0, 11);
|
assert.position(session.documentToScreenPosition(0, 11), 0, 11);
|
||||||
assert.position(session.documentToScreenPosition(0, 12), 1, 0);
|
assert.position(session.documentToScreenPosition(0, 12), 1, 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
"test: documentToScreen with soft wrap and multibyte characters": function() {
|
"test: documentToScreen with soft wrap and multibyte characters": function() {
|
||||||
|
|
||||||
session = new EditSession(["ぁぁa"]);
|
session = new EditSession(["ぁぁa"]);
|
||||||
|
|
@ -298,7 +298,7 @@ module.exports = {
|
||||||
|
|
||||||
"test: documentToScreen should clip position to the document boundaries": function() {
|
"test: documentToScreen should clip position to the document boundaries": function() {
|
||||||
var session = new EditSession("foo bar\njuhu kinners");
|
var session = new EditSession("foo bar\njuhu kinners");
|
||||||
|
|
||||||
assert.position(session.documentToScreenPosition(-1, 4), 0, 0);
|
assert.position(session.documentToScreenPosition(-1, 4), 0, 0);
|
||||||
assert.position(session.documentToScreenPosition(3, 0), 1, 12);
|
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, 12), 0, 11);
|
||||||
assert.position(session.screenToDocumentPosition(0, 20), 0, 11);
|
assert.position(session.screenToDocumentPosition(0, 20), 0, 11);
|
||||||
},
|
},
|
||||||
|
|
||||||
"test: screenToDocument with soft wrap and multi byte characters": function() {
|
"test: screenToDocument with soft wrap and multi byte characters": function() {
|
||||||
session = new EditSession(["ぁ a"]);
|
session = new EditSession(["ぁ a"]);
|
||||||
session.setUseWrapMode(true);
|
session.setUseWrapMode(true);
|
||||||
|
|
@ -352,10 +352,10 @@ module.exports = {
|
||||||
assert.position(session.screenToDocumentPosition(0, 4), 0, 3);
|
assert.position(session.screenToDocumentPosition(0, 4), 0, 3);
|
||||||
assert.position(session.screenToDocumentPosition(0, 5), 0, 3);
|
assert.position(session.screenToDocumentPosition(0, 5), 0, 3);
|
||||||
},
|
},
|
||||||
|
|
||||||
"test: screenToDocument should clip position to the document boundaries": function() {
|
"test: screenToDocument should clip position to the document boundaries": function() {
|
||||||
var session = new EditSession("foo bar\njuhu kinners");
|
var session = new EditSession("foo bar\njuhu kinners");
|
||||||
|
|
||||||
assert.position(session.screenToDocumentPosition(-1, 4), 0, 0);
|
assert.position(session.screenToDocumentPosition(-1, 4), 0, 0);
|
||||||
assert.position(session.screenToDocumentPosition(0, -1), 0, 0);
|
assert.position(session.screenToDocumentPosition(0, -1), 0, 0);
|
||||||
assert.position(session.screenToDocumentPosition(0, 30), 0, 7);
|
assert.position(session.screenToDocumentPosition(0, 30), 0, 7);
|
||||||
|
|
@ -649,7 +649,7 @@ module.exports = {
|
||||||
var session = createFoldTestSession();
|
var session = createFoldTestSession();
|
||||||
var undoManager = session.getUndoManager();
|
var undoManager = session.getUndoManager();
|
||||||
var foldLines = session.$foldData;
|
var foldLines = session.$foldData;
|
||||||
|
|
||||||
function insert(row, column, text) {
|
function insert(row, column, text) {
|
||||||
session.insert({row: row, column: 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, 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