Merge remote-tracking branch 'nightwing/pullreq'
This commit is contained in:
commit
7f8235c0dd
20 changed files with 452 additions and 86 deletions
|
|
@ -105,6 +105,9 @@
|
|||
white-space: nowrap;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
}
|
||||
|
||||
.ace_text-layer {
|
||||
|
|
@ -182,5 +185,41 @@
|
|||
}
|
||||
|
||||
.ace_dragging .ace_content {
|
||||
cursor: move;
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.ace_folding-enabled .ace_gutter-cell {
|
||||
padding-right: 9px!important;
|
||||
}
|
||||
|
||||
.ace_fold-widget {
|
||||
margin-right: -9px;
|
||||
display: inline-block;
|
||||
height: 9px;
|
||||
width: 9px;
|
||||
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAAZdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41Ljg3O4BdAAAAbUlEQVQoU2NgoBqIiIibCcRn0tPzbufmlt4uKam+XVXVdLuhoeN2UVHlGSCeCbYsMTHjdlxcSjOyzSB+a2vvbbhYXV2rGsgkoIQvSBBEg0wCiaM4GSQAsg5kAsg6DAUw1SAJkJtwKkBWSFaoAADKrzXSD2pEpgAAAABJRU5ErkJggg==") no-repeat;
|
||||
background-origin: content-box;
|
||||
padding: 1px 0;
|
||||
}
|
||||
|
||||
.ace_fold-widget.end{
|
||||
transform: scaleY(-1);
|
||||
-moz-transform: scaleY(-1);
|
||||
-webkit-transform: scaleY(-1);
|
||||
opacity:0.8;
|
||||
}
|
||||
|
||||
.ace_fold-widget.closed{
|
||||
-moz-transform: none;
|
||||
-webkit-transform: none;
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJBAMAAAASvxsjAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAC1QTFRF////fn6FXl5kXl5kWFhecnJ5WFhecnJ5YWFoZ2dubW11dHR7enqCgICIhYWNjO3uwQAAAA90Uk5TACZNg5mZzMzb29vb29vbP7t0EwAAACtJREFUCFtjYAhgAIE6ARB5+SKIPKAD4mxg3ggkF2iB2JMngsQzwGocgBgA2zEHmb0961QAAAAASUVORK5CYII=");
|
||||
}
|
||||
|
||||
.ace_fold-widget:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAAZdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41Ljg3O4BdAAAASklEQVQoU2NgoBqQWHFlJhD/lzny/TY6BomD5MGWgSQPvPj5H4bXP4GwQeJw1wA5augKoaaqoTgZWSFWBTDVMIUgGq+nCSrApRsAuCZYT+KbmI0AAAAASUVORK5CYII=");
|
||||
}
|
||||
|
||||
.ace_fold-widget.closed:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJBAMAAAASvxsjAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABVQTFRF////HMT3GKjUHMT3GKjUr+T5wOj5rFcpYAAAAAR0Uk5TACaZ2z7RZscAAAAkSURBVAhbY2BQYAABZwEQaWYIIk2TQRyzNBDHDMI2RKgBqQcAaNgD0/oixWYAAAAASUVORK5CYII=");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -515,6 +515,8 @@ var EditSession = function(text, mode) {
|
|||
this.tokenRe = mode.tokenRe;
|
||||
this.nonTokenRe = mode.nonTokenRe;
|
||||
|
||||
this.$setFolding(mode);
|
||||
|
||||
this._dispatchEvent("changeMode");
|
||||
};
|
||||
|
||||
|
|
@ -835,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);
|
||||
|
||||
|
|
@ -857,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;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ define(function(require, exports, module) {
|
|||
var Range = require("../range").Range;
|
||||
var FoldLine = require("./fold_line").FoldLine;
|
||||
var Fold = require("./fold").Fold;
|
||||
var TokenIterator = require("../token_iterator").TokenIterator;
|
||||
|
||||
function Folding() {
|
||||
/**
|
||||
|
|
@ -247,6 +248,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 +262,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) {
|
||||
|
|
@ -542,25 +534,7 @@ function Folding() {
|
|||
|
||||
range.start.column++;
|
||||
} else {
|
||||
var token = this.getTokenAt(cursor.row, cursor.column);
|
||||
if (token && /^comment|string/.test(token.type)) {
|
||||
var startRow = cursor.row;
|
||||
var endRow = cursor.row;
|
||||
var t = token;
|
||||
while ((t = this.getTokenAt(startRow - 1)) && t.type == token.type) {
|
||||
startRow --;
|
||||
token = t;
|
||||
}
|
||||
range.start.row = startRow;
|
||||
range.start.column = token.start + 2;
|
||||
|
||||
while ((t = this.getTokenAt(endRow + 1, 0)) && t.type == token.type) {
|
||||
endRow ++;
|
||||
token = t;
|
||||
}
|
||||
range.end.row = endRow;
|
||||
range.end.column = token.start + token.value.length - 1;
|
||||
}
|
||||
range = this.getCommentFoldRange(cursor.row, cursor.column) || range;
|
||||
}
|
||||
} else {
|
||||
var folds = this.getFoldsInRange(range);
|
||||
|
|
@ -580,7 +554,6 @@ function Folding() {
|
|||
return
|
||||
}
|
||||
|
||||
|
||||
var placeholder = "...";
|
||||
if (!range.isMultiLine()) {
|
||||
placeholder = this.getTextRange(range);
|
||||
|
|
@ -591,7 +564,215 @@ function Folding() {
|
|||
|
||||
this.addFold(placeholder, range);
|
||||
};
|
||||
|
||||
this.getCommentFoldRange = function(row, column) {
|
||||
var iterator = new TokenIterator(this, row, column);
|
||||
var token = iterator.getCurrentToken();
|
||||
if (token && /^comment|string/.test(token.type)) {
|
||||
var range = new Range;
|
||||
do {
|
||||
t = iterator.stepBackward();
|
||||
} while(t && t.type == token.type)
|
||||
|
||||
iterator.stepForward();
|
||||
range.start.row = iterator.getCurrentTokenRow();
|
||||
range.start.column = iterator.getCurrentTokenColumn() + 2;
|
||||
|
||||
var iterator = new TokenIterator(this, row, column);
|
||||
|
||||
do {
|
||||
t = iterator.stepForward();
|
||||
} while(t && t.type == token.type)
|
||||
t = iterator.stepBackward();
|
||||
|
||||
range.end.row = iterator.getCurrentTokenRow();
|
||||
range.end.column = iterator.getCurrentTokenColumn() + t.value.length - 1;
|
||||
return range
|
||||
}
|
||||
};
|
||||
|
||||
this.foldAll = function() {
|
||||
var foldWidgets = this.foldWidgets
|
||||
for (var row = foldWidgets.length; row--; ) {
|
||||
if (foldWidgets[row] == null)
|
||||
foldWidgets[row] = this.getFoldWidget(row)
|
||||
if (foldWidgets[row] != "start")
|
||||
continue
|
||||
|
||||
var range = this.getFoldWidgetRange(row);
|
||||
console.log(row, range)
|
||||
if (range)
|
||||
this.addFold("...", range)
|
||||
}
|
||||
}
|
||||
|
||||
// structured folding
|
||||
this.$setFolding = function(mode) {
|
||||
mode = mode && mode.foldingRules;
|
||||
var foldRules = Folding.commonFoldingRules
|
||||
if (typeof mode == "string")
|
||||
mode = foldRules[mode];
|
||||
|
||||
if (mode) {
|
||||
this.foldWidgets = [];
|
||||
this.removeListener('change', this.$updateFoldWidgets);
|
||||
|
||||
if (mode.getFoldWidget)
|
||||
this.getFoldWidget = mode.getFoldWidget;
|
||||
else if (mode.foldingStopMarker)
|
||||
this.getFoldWidget = foldRules.$testBoth;
|
||||
else
|
||||
this.getFoldWidget = foldRules.$testStart;
|
||||
|
||||
this.foldingStopMarker = mode.foldingStopMarker;
|
||||
this.foldingStartMarker = mode.foldingStartMarker;
|
||||
|
||||
if (typeof mode.getFoldWidgetRange == "string")
|
||||
this.getFoldWidgetRange = foldRules[mode.getFoldWidgetRange];
|
||||
else
|
||||
this.getFoldWidgetRange = mode.getFoldWidgetRange;
|
||||
|
||||
|
||||
this.$updateFoldWidgets = (mode.onChange || foldRules.onChange).bind(this);
|
||||
|
||||
this.on('change', this.$updateFoldWidgets);
|
||||
} else {
|
||||
this.foldWidgets = null;
|
||||
this.removeListener('change', this.$updateFoldWidgets);
|
||||
}
|
||||
};
|
||||
|
||||
this.onFoldWidgetClick = function(row, htmlEvent) {
|
||||
var type = this.getFoldWidget(row);
|
||||
var line = this.getLine(row);
|
||||
|
||||
if (type == "end")
|
||||
var fold = this.getFoldAt(row, 0, -1);
|
||||
else
|
||||
var fold = this.getFoldAt(row, line.length, 1);
|
||||
|
||||
if (fold) {
|
||||
this.expandFold(fold);
|
||||
return;
|
||||
}
|
||||
|
||||
range = this.getFoldWidgetRange(row);
|
||||
if (range)
|
||||
this.addFold("...", range);
|
||||
}
|
||||
}
|
||||
|
||||
Folding.commonFoldingRules = {
|
||||
$testStart: function(row) {
|
||||
if(this.foldingStartMarker.test(this.getLine(row)))
|
||||
return "start";
|
||||
return "";
|
||||
},
|
||||
$testBoth: function(row) {
|
||||
var line = this.getLine(row);
|
||||
if(this.foldingStartMarker.test(line))
|
||||
return "start";
|
||||
if(this.foldingStopMarker.test(line))
|
||||
return "end";
|
||||
return "";
|
||||
},
|
||||
onChange: function(e) {
|
||||
var delta = e.data;
|
||||
var range = delta.range;
|
||||
var firstRow = range.start.row;
|
||||
var len = range.end.row - firstRow;
|
||||
|
||||
if (len == 0) {
|
||||
this.foldWidgets[firstRow] = null;
|
||||
} else if (delta.action == "removeText" || delta.action == "removeLines") {
|
||||
this.foldWidgets.splice(firstRow, len + 1, null);
|
||||
} else {
|
||||
var args = Array(len + 1);
|
||||
args.unshift(firstRow, 1)
|
||||
this.foldWidgets.splice.apply(this.foldWidgets, args);
|
||||
}
|
||||
},
|
||||
|
||||
indentationBlock: function(row) {
|
||||
var re = /^\s*/;
|
||||
var startRow = row, endRow = row;
|
||||
var line = this.getLine(row);
|
||||
var startColumn = line.length - 1;
|
||||
var startLevel = line.match(re)[0].length;
|
||||
|
||||
while (line = this.getLine(++row)) {
|
||||
var level = line.match(re)[0].length;
|
||||
|
||||
if (level == line.length)
|
||||
continue;
|
||||
|
||||
if (level <= startLevel)
|
||||
break;
|
||||
|
||||
endRow = row;
|
||||
}
|
||||
|
||||
if (endRow > startRow) {
|
||||
endColumn = this.getLine(endRow).length;
|
||||
return new Range(startRow, startColumn, endRow, endColumn);
|
||||
}
|
||||
},
|
||||
|
||||
"cStyle": {
|
||||
foldingStartMarker : /(\{|\[)[^\}\]]*$|^\s*(\/\*)/,
|
||||
foldingStopMarker : /^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,
|
||||
getFoldWidgetRange: function(row) {
|
||||
var line = this.getLine(row);
|
||||
var match = line.match(this.foldingStartMarker);
|
||||
if (match) {
|
||||
var i = match.index;
|
||||
|
||||
if (match[2])
|
||||
return this.getCommentFoldRange(row, i + match[0].length);
|
||||
|
||||
var start = {row: row, column: i+1};
|
||||
var end = this.$findClosingBracket(match[1], start);
|
||||
if (end) {
|
||||
var fw = this.foldWidgets[end.row];
|
||||
if (fw == null)
|
||||
fw = this.getFoldWidget(end.row);
|
||||
|
||||
if (fw == "start"){
|
||||
end.row --;
|
||||
end.column = this.getLine(end.row).length;
|
||||
}
|
||||
|
||||
} else {
|
||||
end = {row: this.getLength(), column: 0};
|
||||
}
|
||||
|
||||
return Range.fromPoints(start, end);
|
||||
}
|
||||
|
||||
var match = line.match(this.foldingStopMarker);
|
||||
if (match) {
|
||||
var i = match.index + match[0].length;
|
||||
|
||||
if (match[2])
|
||||
return this.getCommentFoldRange(row, i);
|
||||
|
||||
var end = {row: row, column: i};
|
||||
var start = this.$findOpeningBracket(match[1], end)
|
||||
if (start){
|
||||
start.column++;
|
||||
end.column--;
|
||||
} else {
|
||||
start = {row: 0, column: this.getLine(0).length}
|
||||
}
|
||||
|
||||
return Range.fromPoints(start, end);
|
||||
}
|
||||
}
|
||||
},
|
||||
// TODO: folding based only on indentation
|
||||
"indentation": null
|
||||
}
|
||||
|
||||
exports.Folding = Folding;
|
||||
|
||||
});
|
||||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -637,6 +637,19 @@ var Editor = function(renderer, session) {
|
|||
return this.$modeBehaviours;
|
||||
};
|
||||
|
||||
this.setShowFoldWidgets = function(show) {
|
||||
var gutter = this.renderer.$gutterLayer;
|
||||
if (gutter.getShowFoldWidgets() == show)
|
||||
return;
|
||||
|
||||
this.renderer.$gutterLayer.setShowFoldWidgets(show);
|
||||
this.$showFoldWidgets = show;
|
||||
this.renderer.updateFull();
|
||||
};
|
||||
this.getShowFoldWidgets = function() {
|
||||
return this.renderer.$gutterLayer.getShowFoldWidgets();
|
||||
};
|
||||
|
||||
this.remove = function(dir) {
|
||||
if (this.selection.isEmpty()){
|
||||
if(dir == "left")
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ var Gutter = function(parentEl) {
|
|||
this.element = dom.createElement("div");
|
||||
this.element.className = "ace_layer ace_gutter-layer";
|
||||
parentEl.appendChild(this.element);
|
||||
this.setShowFoldWidgets(this.$showFoldWidgets);
|
||||
|
||||
this.$breakpoints = [];
|
||||
this.$annotations = [];
|
||||
|
|
@ -105,6 +106,7 @@ var Gutter = function(parentEl) {
|
|||
var lastRow = config.lastRow;
|
||||
var fold = this.session.getNextFoldLine(i);
|
||||
var foldStart = fold ? fold.start.row : Infinity;
|
||||
var foldWidgets = this.$showFoldWidgets && this.session.foldWidgets;
|
||||
|
||||
while (true) {
|
||||
if(i > foldStart) {
|
||||
|
|
@ -123,6 +125,18 @@ var Gutter = function(parentEl) {
|
|||
"' title='", annotation.text.join("\n"),
|
||||
"' style='height:", config.lineHeight, "px;'>", (i+1));
|
||||
|
||||
if (foldWidgets) {
|
||||
var c = foldWidgets[i];
|
||||
if (c == null)
|
||||
c = foldWidgets[i] = this.session.getFoldWidget(i);
|
||||
if(c)
|
||||
html.push(
|
||||
"<span class='ace_fold-widget ", c,
|
||||
c == "start" && i == foldStart && i < fold.end.row ? " closed" : " open",
|
||||
"'></span>"
|
||||
);
|
||||
}
|
||||
|
||||
var wrappedRowLength = this.session.getRowLength(i) - 1;
|
||||
while (wrappedRowLength--) {
|
||||
html.push("</div><div class='ace_gutter-cell' style='height:", config.lineHeight, "px'>\xA6");
|
||||
|
|
@ -136,6 +150,19 @@ var Gutter = function(parentEl) {
|
|||
this.element.style.height = config.minHeight + "px";
|
||||
};
|
||||
|
||||
this.$showFoldWidgets = true;
|
||||
this.setShowFoldWidgets = function(show) {
|
||||
if (show)
|
||||
dom.addCssClass(this.element, "ace_folding-enabled");
|
||||
else
|
||||
dom.removeCssClass(this.element, "ace_folding-enabled");
|
||||
|
||||
this.$showFoldWidgets = show;
|
||||
};
|
||||
this.getShowFoldWidgets = function() {
|
||||
return this.$showFoldWidgets;
|
||||
};
|
||||
|
||||
}).call(Gutter.prototype);
|
||||
|
||||
exports.Gutter = Gutter;
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ var EventEmitter = require("../lib/event_emitter").EventEmitter;
|
|||
var Text = function(parentEl) {
|
||||
this.element = dom.createElement("div");
|
||||
this.element.className = "ace_layer ace_text-layer";
|
||||
this.element.style.width = "auto";
|
||||
parentEl.appendChild(this.element);
|
||||
|
||||
this.$characterSize = this.$measureSizes() || {width: 0, height: 0};
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ oop.inherits(Mode, TextMode);
|
|||
|
||||
(function() {
|
||||
|
||||
this.foldingRules = "cStyle";
|
||||
|
||||
this.toggleCommentLines = function(state, doc, startRow, endRow) {
|
||||
var outdent = true;
|
||||
var outentedRows = [];
|
||||
|
|
|
|||
|
|
@ -16,34 +16,36 @@ oop.inherits(Mode, TextMode);
|
|||
|
||||
(function() {
|
||||
|
||||
this.getNextLineIndent = function(state, line, tab) {
|
||||
var indent = this.$getIndent(line);
|
||||
this.foldingRules = "cStyle";
|
||||
|
||||
var tokenizedLine = this.$tokenizer.getLineTokens(line, state);
|
||||
var tokens = tokenizedLine.tokens;
|
||||
var endState = tokenizedLine.state;
|
||||
this.getNextLineIndent = function(state, line, tab) {
|
||||
var indent = this.$getIndent(line);
|
||||
|
||||
var tokenizedLine = this.$tokenizer.getLineTokens(line, state);
|
||||
var tokens = tokenizedLine.tokens;
|
||||
var endState = tokenizedLine.state;
|
||||
|
||||
if (tokens.length && tokens[tokens.length-1].type == "comment") {
|
||||
return indent;
|
||||
}
|
||||
|
||||
if (state == "start") {
|
||||
var match = line.match(/^.*[\{\(\[]\s*$/);
|
||||
if (match) {
|
||||
indent += tab;
|
||||
}
|
||||
}
|
||||
|
||||
return indent;
|
||||
};
|
||||
|
||||
if (tokens.length && tokens[tokens.length-1].type == "comment") {
|
||||
return indent;
|
||||
}
|
||||
|
||||
if (state == "start") {
|
||||
var match = line.match(/^.*[\{\(\[]\s*$/);
|
||||
if (match) {
|
||||
indent += tab;
|
||||
}
|
||||
}
|
||||
|
||||
return indent;
|
||||
};
|
||||
|
||||
this.checkOutdent = function(state, line, input) {
|
||||
return this.$outdent.checkOutdent(line, input);
|
||||
};
|
||||
|
||||
this.autoOutdent = function(state, doc, row) {
|
||||
this.$outdent.autoOutdent(doc, row);
|
||||
};
|
||||
this.checkOutdent = function(state, line, input) {
|
||||
return this.$outdent.checkOutdent(line, input);
|
||||
};
|
||||
|
||||
this.autoOutdent = function(state, doc, row) {
|
||||
this.$outdent.autoOutdent(doc, row);
|
||||
};
|
||||
|
||||
|
||||
this.createWorker = function(session) {
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ oop.inherits(Mode, TextMode);
|
|||
|
||||
(function() {
|
||||
|
||||
this.foldingRules = "cStyle";
|
||||
|
||||
this.getNextLineIndent = function(state, line, tab) {
|
||||
var indent = this.$getIndent(line);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ oop.inherits(Mode, JavaScriptMode);
|
|||
|
||||
(function() {
|
||||
|
||||
this.foldingRules = "cStyle";
|
||||
|
||||
this.createWorker = function(session) {
|
||||
return null;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ oop.inherits(Mode, TextMode);
|
|||
|
||||
(function() {
|
||||
|
||||
this.foldingRules = "cStyle";
|
||||
|
||||
this.toggleCommentLines = function(state, doc, startRow, endRow) {
|
||||
var outdent = true;
|
||||
var re = /^(\s*)\/\//;
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ oop.inherits(Mode, TextMode);
|
|||
|
||||
(function() {
|
||||
|
||||
this.foldingRules = "cStyle";
|
||||
|
||||
this.getNextLineIndent = function(state, line, tab) {
|
||||
var indent = this.$getIndent(line);
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,11 @@ oop.inherits(Mode, TextMode);
|
|||
|
||||
(function() {
|
||||
|
||||
this.foldingRules = {
|
||||
foldingStartMarker: /\:(:?\s*)?(:?#.*)?$/,
|
||||
getFoldWidgetRange: "indentationBlock"
|
||||
};
|
||||
|
||||
this.toggleCommentLines = function(state, doc, startRow, endRow) {
|
||||
var outdent = true;
|
||||
var outentedRows = [];
|
||||
|
|
|
|||
|
|
@ -259,7 +259,10 @@ function DefaultHandlers(editor) {
|
|||
// If the user dclicked on a fold, then expand it.
|
||||
var fold = editor.session.getFoldAt(pos.row, pos.column, 1);
|
||||
if (fold) {
|
||||
editor.session.expandFold(fold);
|
||||
if (ev.getAccelKey())
|
||||
editor.session.removeFold(fold);
|
||||
else
|
||||
editor.session.expandFold(fold);
|
||||
}
|
||||
else {
|
||||
editor.moveCursorToPosition(pos);
|
||||
|
|
|
|||
|
|
@ -128,6 +128,10 @@ var MouseEvent = exports.MouseEvent = function(domEvent, editor) {
|
|||
return this.domEvent.shiftKey;
|
||||
};
|
||||
|
||||
this.getAccelKey = function() {
|
||||
return this.domEvent.ctrlKey || this.domEvent.metaKey ;
|
||||
};
|
||||
|
||||
}).call(MouseEvent.prototype);
|
||||
|
||||
});
|
||||
|
|
@ -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,14 @@ 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;
|
||||
|
||||
if (e.target.className.indexOf('ace_fold-widget') != -1)
|
||||
return this.session.onFoldWidgetClick(row, e);
|
||||
|
||||
this._dispatchEvent("gutter" + e.type, {
|
||||
row: this.screenToTextCoordinates(pageX, pageY).row,
|
||||
row: row,
|
||||
htmlEvent: e
|
||||
});
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue