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 ++;
} else {
tokens = [];
foldLine.walk(
function(placeholder, row, column, lastColumn) {
foldLine.walk(function(placeholder, row, column, lastColumn) {
var walkTokens;
if (placeholder) {
if (placeholder != null) {
walkTokens = this.$getDisplayTokens(
placeholder, tokens.length);
walkTokens[0] = PLACEHOLDER_START;

View file

@ -274,9 +274,6 @@ function Folding() {
var endColumn = fold.end.column;
// --- Some checking ---
if (fold.placeholder.length < 2)
throw "Placeholder has to be at least 2 characters";
if (startRow == endRow && endColumn - startColumn < 2)
throw "The range has to be at least 2 characters width";
@ -489,7 +486,7 @@ function Folding() {
}
lastColumn = Math.max(startColumn, lastColumn);
}
if (placeholder) {
if (placeholder != null) {
textLine += placeholder;
} else {
textLine += doc.getLine(row).substring(lastColumn, column);
@ -588,30 +585,34 @@ function Folding() {
this.addFold(placeholder, range);
};
this.getCommentFoldRange = function(row, column) {
this.getCommentFoldRange = function(row, column, dir) {
var iterator = new TokenIterator(this, row, column);
var token = iterator.getCurrentToken();
if (token && /^comment|string/.test(token.type)) {
var range = new Range();
var re = new RegExp(token.type.replace(/\..*/, "\\."));
do {
token = iterator.stepBackward();
} while(token && re.test(token.type));
iterator.stepForward();
if (dir != 1) {
do {
token = iterator.stepBackward();
} while(token && re.test(token.type));
iterator.stepForward();
}
range.start.row = iterator.getCurrentTokenRow();
range.start.column = iterator.getCurrentTokenColumn() + 2;
iterator = new TokenIterator(this, row, column);
do {
token = iterator.stepForward();
} while(token && re.test(token.type));
token = iterator.stepBackward();
if (dir != -1) {
do {
token = iterator.stepForward();
} while(token && re.test(token.type));
token = iterator.stepBackward();
} else
token = iterator.getCurrentToken();
range.end.row = iterator.getCurrentTokenRow();
range.end.column = iterator.getCurrentTokenColumn() + token.value.length;
range.end.column = iterator.getCurrentTokenColumn() + token.value.length - 2;
return range;
}
};
@ -628,7 +629,7 @@ function Folding() {
var range = this.getFoldWidgetRange(row);
// sometimes range can be incompatible with existing fold
// 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);
} catch(e) {}
}
@ -722,7 +723,7 @@ function Folding() {
} else {
if (addSubfolds)
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);
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);
assert.equal(session.$foldData[0].folds.length, 2);
session.removeFold(fold);

View file

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

View file

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

View file

@ -3,7 +3,7 @@
*
* Copyright (c) 2010, Ajax.org B.V.
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
@ -14,7 +14,7 @@
* * Neither the name of Ajax.org B.V. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@ -42,7 +42,7 @@ oop.inherits(FoldMode, BaseFoldMode);
this.foldingStartMarker = /(\{|\[)[^\}\]]*$|^\s*(\/\*)/;
this.foldingStopMarker = /^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/;
this.getFoldWidgetRange = function(session, foldStyle, row) {
var line = session.getLine(row);
var match = line.match(this.foldingStartMarker);
@ -52,37 +52,23 @@ oop.inherits(FoldMode, BaseFoldMode);
if (match[1])
return this.openingBracketBlock(session, match[1], row, i);
var range = session.getCommentFoldRange(row, i + match[0].length);
range.end.column -= 2;
return range;
return session.getCommentFoldRange(row, i + match[0].length, 1);
}
if (foldStyle !== "markbeginend")
return;
var match = line.match(this.foldingStopMarker);
if (match) {
var i = match.index + match[0].length;
if (match[2]) {
var range = session.getCommentFoldRange(row, i);
range.end.column -= 2;
return range;
}
if (match[1])
return this.closingBracketBlock(session, match[1], row, i);
var end = {row: row, column: i};
var start = session.$findOpeningBracket(match[1], end);
if (!start)
return;
start.column++;
end.column--;
return Range.fromPoints(start, end);
return session.getCommentFoldRange(row, i, -1);
}
};
}).call(FoldMode.prototype);
});

View file

@ -3,7 +3,7 @@
*
* Copyright (c) 2010, Ajax.org B.V.
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
@ -14,7 +14,7 @@
* * Neither the name of Ajax.org B.V. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@ -103,6 +103,18 @@ var FoldMode = exports.FoldMode = function() {};
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);
});

View file

@ -3,7 +3,7 @@
*
* Copyright (c) 2010, Ajax.org B.V.
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
@ -14,7 +14,7 @@
* * Neither the name of Ajax.org B.V. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

View file

@ -3,7 +3,7 @@
*
* Copyright (c) 2010, Ajax.org B.V.
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
@ -14,7 +14,7 @@
* * Neither the name of Ajax.org B.V. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@ -32,11 +32,11 @@ define(function(require, exports, module) {
"use strict";
function FoldHandler(editor) {
editor.on("click", function(e) {
var position = e.getDocumentPosition();
var session = editor.session;
// If the user clicked on a fold, then expand it.
var fold = session.getFoldAt(position.row, position.column, 1);
if (fold) {
@ -44,12 +44,12 @@ function FoldHandler(editor) {
session.removeFold(fold);
else
session.expandFold(fold);
e.stop();
}
});
editor.on("gutterclick", function(e) {
editor.on("guttermousedown", function(e) {
var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
if (gutterRegion == "foldWidgets") {
@ -60,6 +60,49 @@ function FoldHandler(editor) {
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;