Merge pull request #1085 from ajaxorg/folding-2

improve folding behavior
This commit is contained in:
Mostafa Eweda 2012-11-06 23:48:06 -08:00
commit 2c86ab5bcd
9 changed files with 99 additions and 58 deletions

View file

@ -1899,10 +1899,9 @@ var EditSession = function(text, mode) {
row ++; row ++;
} else { } else {
tokens = []; tokens = [];
foldLine.walk( foldLine.walk(function(placeholder, row, column, lastColumn) {
function(placeholder, row, column, lastColumn) {
var walkTokens; var walkTokens;
if (placeholder) { if (placeholder != null) {
walkTokens = this.$getDisplayTokens( walkTokens = this.$getDisplayTokens(
placeholder, tokens.length); placeholder, tokens.length);
walkTokens[0] = PLACEHOLDER_START; walkTokens[0] = PLACEHOLDER_START;

View file

@ -274,9 +274,6 @@ function Folding() {
var endColumn = fold.end.column; var endColumn = fold.end.column;
// --- Some checking --- // --- Some checking ---
if (fold.placeholder.length < 2)
throw "Placeholder has to be at least 2 characters";
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";
@ -489,7 +486,7 @@ function Folding() {
} }
lastColumn = Math.max(startColumn, lastColumn); lastColumn = Math.max(startColumn, lastColumn);
} }
if (placeholder) { if (placeholder != null) {
textLine += placeholder; textLine += placeholder;
} else { } else {
textLine += doc.getLine(row).substring(lastColumn, column); textLine += doc.getLine(row).substring(lastColumn, column);
@ -588,30 +585,34 @@ function Folding() {
this.addFold(placeholder, range); this.addFold(placeholder, range);
}; };
this.getCommentFoldRange = function(row, column) { this.getCommentFoldRange = function(row, column, dir) {
var iterator = new TokenIterator(this, row, column); var iterator = new TokenIterator(this, row, column);
var token = iterator.getCurrentToken(); var token = iterator.getCurrentToken();
if (token && /^comment|string/.test(token.type)) { if (token && /^comment|string/.test(token.type)) {
var range = new Range(); var range = new Range();
var re = new RegExp(token.type.replace(/\..*/, "\\.")); var re = new RegExp(token.type.replace(/\..*/, "\\."));
do { if (dir != 1) {
token = iterator.stepBackward(); do {
} while(token && re.test(token.type)); token = iterator.stepBackward();
} while(token && re.test(token.type));
iterator.stepForward();
}
iterator.stepForward();
range.start.row = iterator.getCurrentTokenRow(); range.start.row = iterator.getCurrentTokenRow();
range.start.column = iterator.getCurrentTokenColumn() + 2; range.start.column = iterator.getCurrentTokenColumn() + 2;
iterator = new TokenIterator(this, row, column); iterator = new TokenIterator(this, row, column);
do { if (dir != -1) {
token = iterator.stepForward(); do {
} while(token && re.test(token.type)); token = iterator.stepForward();
} while(token && re.test(token.type));
token = iterator.stepBackward(); token = iterator.stepBackward();
} else
token = iterator.getCurrentToken();
range.end.row = iterator.getCurrentTokenRow(); range.end.row = iterator.getCurrentTokenRow();
range.end.column = iterator.getCurrentTokenColumn() + token.value.length; range.end.column = iterator.getCurrentTokenColumn() + token.value.length - 2;
return range; return range;
} }
}; };
@ -628,7 +629,7 @@ function Folding() {
var range = this.getFoldWidgetRange(row); var range = this.getFoldWidgetRange(row);
// sometimes range can be incompatible with existing fold // sometimes range can be incompatible with existing fold
// wouldn't it be better for addFold to return null istead of throwing? // wouldn't it be better for addFold to return null istead of throwing?
if (range && range.end.row < endRow) try { if (range && range.end.row <= endRow) try {
this.addFold("...", range); this.addFold("...", range);
} catch(e) {} } catch(e) {}
} }
@ -722,7 +723,7 @@ function Folding() {
} else { } else {
if (addSubfolds) if (addSubfolds)
this.foldAll(row + 1, this.getLength()); this.foldAll(row + 1, this.getLength());
(e.target || e.srcElement).className += " invalid" (e.target || e.srcElement).className += " ace_invalid"
} }
}; };

View file

@ -920,7 +920,7 @@ module.exports = {
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);
tryAddFold("f", new Range(0, 13, 0, 18), true); tryAddFold("f", new Range(0, 13, 0, 18), false);
tryAddFold("foo", new Range(0, 18, 0, 21), false); tryAddFold("foo", new Range(0, 18, 0, 21), false);
assert.equal(session.$foldData[0].folds.length, 2); assert.equal(session.$foldData[0].folds.length, 2);
session.removeFold(fold); session.removeFold(fold);

View file

@ -616,7 +616,7 @@ var Text = function(parentEl) {
var tokens = session.getTokens(row); var tokens = session.getTokens(row);
foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) { foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) {
if (placeholder) { if (placeholder != null) {
renderTokens.push({ renderTokens.push({
type: "fold", type: "fold",
value: placeholder value: placeholder

View file

@ -39,7 +39,7 @@ var FoldMode = exports.FoldMode = function() {};
oop.inherits(FoldMode, BaseFoldMode); oop.inherits(FoldMode, BaseFoldMode);
(function() { (function() {
this.foldingStartMarker = /^(?:\|={10,}|[\.\/=\-~^+]{4,}|={1,5} )/; this.foldingStartMarker = /^(?:\|={10,}|[\.\/=\-~^+]{4,}\s*$|={1,5} )/;
this.singleLineHeadingRe = /^={1,5}(?=\s+\S)/; this.singleLineHeadingRe = /^={1,5}(?=\s+\S)/;
this.getFoldWidget = function(session, foldStyle, row) { this.getFoldWidget = function(session, foldStyle, row) {

View file

@ -52,9 +52,7 @@ oop.inherits(FoldMode, BaseFoldMode);
if (match[1]) if (match[1])
return this.openingBracketBlock(session, match[1], row, i); return this.openingBracketBlock(session, match[1], row, i);
var range = session.getCommentFoldRange(row, i + match[0].length); return session.getCommentFoldRange(row, i + match[0].length, 1);
range.end.column -= 2;
return range;
} }
if (foldStyle !== "markbeginend") if (foldStyle !== "markbeginend")
@ -64,22 +62,10 @@ oop.inherits(FoldMode, BaseFoldMode);
if (match) { if (match) {
var i = match.index + match[0].length; var i = match.index + match[0].length;
if (match[2]) { if (match[1])
var range = session.getCommentFoldRange(row, i); return this.closingBracketBlock(session, match[1], row, i);
range.end.column -= 2;
return range;
}
var end = {row: row, column: i}; return session.getCommentFoldRange(row, i, -1);
var start = session.$findOpeningBracket(match[1], end);
if (!start)
return;
start.column++;
end.column--;
return Range.fromPoints(start, end);
} }
}; };

View file

@ -103,6 +103,18 @@ var FoldMode = exports.FoldMode = function() {};
return Range.fromPoints(start, end); return Range.fromPoints(start, end);
}; };
this.closingBracketBlock = function(session, bracket, row, column, typeRe) {
var end = {row: row, column: column};
var start = session.$findOpeningBracket(bracket, end);
if (!start)
return;
start.column++;
end.column--;
return Range.fromPoints(start, end);
};
}).call(FoldMode.prototype); }).call(FoldMode.prototype);
}); });

View file

@ -49,7 +49,7 @@ function FoldHandler(editor) {
} }
}); });
editor.on("gutterclick", function(e) { editor.on("guttermousedown", function(e) {
var gutterRegion = editor.renderer.$gutterLayer.getRegion(e); var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
if (gutterRegion == "foldWidgets") { if (gutterRegion == "foldWidgets") {
@ -60,6 +60,49 @@ function FoldHandler(editor) {
e.stop(); e.stop();
} }
}); });
editor.on("gutterdblclick", function(e) {
var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
if (gutterRegion == "foldWidgets") {
var row = e.getDocumentPosition().row;
var session = editor.session;
var fw = session.foldWidgets;
if (!fw || fw[row])
return;
var i = row - 1, firstRange;
while (i >= 0) {
var c = fw[i];
if (c == null)
c = fw[i] = session.getFoldWidget();
if (c == "start") {
var range = session.getFoldWidgetRange(i);
if (!firstRange)
firstRange = range;
if (range && range.end.row >= row)
break;
}
i--;
}
if (i == -1)
range = firstRange;
if (range) {
var row = range.start.row;
var fold = session.getFoldAt(row, session.getLine(row).length, 1);
if (fold) {
session.removeFold(fold);
} else {
session.addFold("...", range);
editor.renderer.scrollCursorIntoView({row: range.start.row, column: 0});
}
}
e.stop();
}
});
} }
exports.FoldHandler = FoldHandler; exports.FoldHandler = FoldHandler;