Merge remote-tracking branch 'nightwing/pullreq'

This commit is contained in:
Fabian Jakobs 2011-12-01 11:02:48 +01:00
commit 7f8235c0dd
20 changed files with 452 additions and 86 deletions

View file

@ -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=");
}

View file

@ -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;

View file

@ -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);
});

View file

@ -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;

View file

@ -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;
});

View file

@ -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);
}
};

View file

@ -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")

View file

@ -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;

View file

@ -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};

View file

@ -55,6 +55,8 @@ oop.inherits(Mode, TextMode);
(function() {
this.foldingRules = "cStyle";
this.toggleCommentLines = function(state, doc, startRow, endRow) {
var outdent = true;
var outentedRows = [];

View file

@ -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) {

View file

@ -52,6 +52,8 @@ oop.inherits(Mode, TextMode);
(function() {
this.foldingRules = "cStyle";
this.getNextLineIndent = function(state, line, tab) {
var indent = this.$getIndent(line);

View file

@ -16,6 +16,8 @@ oop.inherits(Mode, JavaScriptMode);
(function() {
this.foldingRules = "cStyle";
this.createWorker = function(session) {
return null;
};

View file

@ -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*)\/\//;

View file

@ -54,6 +54,8 @@ oop.inherits(Mode, TextMode);
(function() {
this.foldingRules = "cStyle";
this.getNextLineIndent = function(state, line, tab) {
var indent = this.$getIndent(line);

View file

@ -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 = [];

View file

@ -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);

View file

@ -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);
});

View file

@ -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 +

View file

@ -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
});
};