split mode specific code for structured folding

into separate files
This commit is contained in:
Fabian Jakobs 2011-12-01 18:19:24 +01:00
commit bbcb00acc4
27 changed files with 567 additions and 452 deletions

View file

@ -515,7 +515,8 @@ var EditSession = function(text, mode) {
this.tokenRe = mode.tokenRe;
this.nonTokenRe = mode.nonTokenRe;
this.$setFolding(mode);
if (mode.foldingRules)
this.$setFolding(mode.foldingRules);
this._dispatchEvent("changeMode");
};

View file

@ -112,7 +112,7 @@ function Folding() {
}
}
return foundFolds;
}
};
/**
* Returns the string between folds at the given position.
@ -132,7 +132,7 @@ function Folding() {
* fo|o<fold>bar<fold>wolrd -trim=00> "foo"
*/
this.getFoldStringAt = function(row, column, trim, foldLine) {
var foldLine = foldLine || this.getFoldLine(row);
foldLine = foldLine || this.getFoldLine(row);
if (!foldLine)
return null;
@ -140,16 +140,17 @@ function Folding() {
end: { column: 0 }
};
// TODO: Refactor to use getNextFoldTo function.
var str, fold;
for (var i = 0; i < foldLine.folds.length; i++) {
var fold = foldLine.folds[i];
fold = foldLine.folds[i];
var cmp = fold.range.compareEnd(row, column);
if (cmp == -1) {
var str = this
str = this
.getLine(fold.start.row)
.substring(lastFold.end.column, fold.start.column);
break;
}
else if (cmp == 0) {
else if (cmp === 0) {
return null;
}
lastFold = fold;
@ -160,10 +161,10 @@ function Folding() {
if (trim == -1)
return str.substring(0, column - lastFold.end.column);
else if (trim == 1)
return str.substring(column - lastFold.end.column)
return str.substring(column - lastFold.end.column);
else
return str;
}
};
this.getFoldLine = function(docRow, startFoldLine) {
var foldData = this.$foldData;
@ -181,11 +182,11 @@ function Folding() {
}
}
return null;
}
};
// returns the fold which starts after or contains docRow
this.getNextFoldLine = function(docRow, startFoldLine) {
var foldData = this.$foldData, ans;
var foldData = this.$foldData;
var i = 0;
if (startFoldLine)
i = foldData.indexOf(startFoldLine);
@ -198,7 +199,7 @@ function Folding() {
}
}
return null;
}
};
this.getFoldedRowCount = function(first, last) {
var foldData = this.$foldData, rowCount = last-first+1;
@ -222,7 +223,7 @@ function Folding() {
}
}
return rowCount;
}
};
this.$addFoldLine = function(foldLine) {
this.$foldData.push(foldLine);
@ -230,7 +231,7 @@ function Folding() {
return a.start.row - b.start.row;
});
return foldLine;
}
};
/**
* Adds a new fold.
@ -242,9 +243,10 @@ function Folding() {
this.addFold = function(placeholder, range) {
var foldData = this.$foldData;
var added = false;
var fold;
if (placeholder instanceof Fold)
var fold = placeholder;
fold = placeholder;
else
fold = new Fold(range, placeholder);
@ -295,7 +297,7 @@ function Folding() {
added = true;
if (!fold.sameRow) {
// Check if we might have to merge two FoldLines.
foldLineNext = foldData[i + 1];
var foldLineNext = foldData[i + 1];
if (foldLineNext && foldLineNext.start.row == endRow) {
// We need to merge!
foldLine.merge(foldLineNext);
@ -376,7 +378,7 @@ function Folding() {
// Notify that fold data has changed.
this.$modified = true;
this._dispatchEvent("changeFold", { data: fold });
}
};
this.removeFolds = function(folds) {
// We need to clone the folds array passed in as it might be the folds
@ -549,7 +551,7 @@ function Folding() {
if (fold && fold.range.toString() == range.toString()){
this.expandFold(fold);
return
return;
}
var placeholder = "...";
@ -557,7 +559,7 @@ function Folding() {
placeholder = this.getTextRange(range);
if(placeholder.length < 4)
return;
placeholder = placeholder.trim().substring(0, 2) + ".."
placeholder = placeholder.trim().substring(0, 2) + "..";
}
this.addFold(placeholder, range);
@ -571,7 +573,7 @@ function Folding() {
var t;
do {
t = iterator.stepBackward();
} while(t && t.type == token.type)
} while(t && t.type == token.type);
iterator.stepForward();
range.start.row = iterator.getCurrentTokenRow();
@ -581,73 +583,60 @@ function Folding() {
do {
t = iterator.stepForward();
} while(t && t.type == token.type)
} 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
return range;
}
};
this.foldAll = function() {
var foldWidgets = this.foldWidgets
var foldWidgets = this.foldWidgets;
for (var row = foldWidgets.length; row--; ) {
if (foldWidgets[row] == null)
foldWidgets[row] = this.getFoldWidget(row)
foldWidgets[row] = this.getFoldWidget(row);
if (foldWidgets[row] != "start")
continue
continue;
var range = this.getFoldWidgetRange(row);
if (range)
this.addFold("...", 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.$setFolding = function(foldMode) {
if (this.$foldMode == foldMode)
return;
this.$foldMode = foldMode;
this.removeListener('change', this.$updateFoldWidgets);
if (!foldMode) {
this.foldWidgets = null;
this.removeListener('change', this.$updateFoldWidgets);
return;
}
this.foldWidgets = [];
this.getFoldWidget = foldMode.getFoldWidget.bind(foldMode, this);
this.getFoldWidgetRange = foldMode.getFoldWidgetRange.bind(foldMode, this);
this.$updateFoldWidgets = this.updateFoldWidgets.bind(this);
this.on('change', this.$updateFoldWidgets);
};
this.onFoldWidgetClick = function(row, htmlEvent) {
var type = this.getFoldWidget(row);
var line = this.getLine(row);
var fold;
if (type == "end")
var fold = this.getFoldAt(row, 0, -1);
fold = this.getFoldAt(row, 0, -1);
else
var fold = this.getFoldAt(row, line.length, 1);
fold = this.getFoldAt(row, line.length, 1);
if (fold) {
this.expandFold(fold);
@ -657,260 +646,25 @@ function Folding() {
var 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) {
};
this.updateFoldWidgets = function(e) {
var delta = e.data;
var range = delta.range;
var firstRow = range.start.row;
var len = range.end.row - firstRow;
if (len == 0) {
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)
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) {
var 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,
"xml": {
voidElements: {
"area": 1,
"base": 1,
"br": 1,
"col": 1,
"command": 1,
"embed": 1,
"hr": 1,
"img": 1,
"input": 1,
"keygen": 1,
"link": 1,
"meta": 1,
"param": 1,
"source": 1,
"track": 1,
"wbr": 1
},
getFoldWidget: function(row) {
var tags = this.getTokens(row, row)[0].tokens
.filter(function(token) {
return token.type === "meta.tag"
})
.map(function(token) {
return token.value;
}).
join("")
.trim()
.replace(/^<|>$|\s+/g, "")
.split("><")
var fold = tags[0];
if (!fold || Folding.commonFoldingRules.xml.voidElements[fold])
return;
if (fold.charAt(0) == "/")
return "end";
if (tags.indexOf("/" + fold) !== -1)
return;
return "start";
},
getFoldWidgetRange: function(row) {
var start, end;
var stack = [];
var iterator = new TokenIterator(this, row, 0);
var step = "stepForward";
var isBack = false;
// http://dev.w3.org/html5/spec/syntax.html#optional-tags
// TODO
// var optionalTags = {
// "html": 1,
// "head": 1,
// "body": 1,
// "li": 1,
// "dt": 1,
// "dd": 1,
// "p": 1,
// "rt": 1,
// "rp": 1,
// "optgroup": 1,
// "option": 1,
// "colgroup": 1,
// "thead": 1,
// "tbody": 1,
// "tfoot": 1,
// "tr": 1,
// "td": 1,
// "th": 1
// };
// limited XML parsing to find matching tag
do {
var token = iterator.getCurrentToken();
var value = token.value.trim();
if (token && token.type == "meta.tag" && token.value !== ">") {
var tagName = value.replace(/^[<\s]*|[\s*>]$/g, "");
if (Folding.commonFoldingRules.xml.voidElements[tagName])
continue;
if (!start) {
if (tagName.charAt(0) == "/") {
tagName = tagName.slice(1);
step = "stepBackward";
isBack = true;
}
start = {
row: row,
column: iterator.getCurrentTokenColumn() + (isBack ? 0 : value.length + 1)
};
// console.log("push", tagName)
stack.push(tagName);
}
else {
if (tagName.charAt(0) == "/") {
tagName = tagName.slice(1);
var close = !isBack;
}
else
close = isBack;
if (close) {
if (stack[stack.length-1] == tagName) {
// console.log("pop", tagName)
stack.pop();
if (stack.length == 0) {
end = {
row: iterator.getCurrentTokenRow(),
column: iterator.getCurrentTokenColumn() + (isBack ? value.length : 0)
};
if (isBack)
return Range.fromPoints(end, start);
else
return Range.fromPoints(start, end);
}
}
else {
// console.error("unmatched tags!", tagName, stack)
}
}
else {
// console.log("push", tagName)
stack.push(tagName);
}
}
}
} while(token = iterator[step]());
}
}
}
exports.Folding = Folding;

View file

@ -45,21 +45,20 @@ var c_cppHighlightRules = require("./c_cpp_highlight_rules").c_cppHighlightRules
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var Range = require("../range").Range;
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
var Mode = function() {
this.$tokenizer = new Tokenizer(new c_cppHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.$behaviour = new CstyleBehaviour();
this.foldingRules = new CStyleFoldMode();
};
oop.inherits(Mode, TextMode);
(function() {
this.foldingRules = "cStyle";
this.toggleCommentLines = function(state, doc, startRow, endRow) {
var outdent = true;
var outentedRows = [];
var re = /^(\s*)\/\//;
for (var i=startRow; i<= endRow; i++) {

View file

@ -56,7 +56,6 @@ oop.inherits(Mode, TextMode);
this.toggleCommentLines = function(state, doc, startRow, endRow) {
var outdent = true;
var outentedRows = [];
var re = /^(\s*)#/;
for (var i=startRow; i<= endRow; i++) {
@ -85,11 +84,9 @@ oop.inherits(Mode, TextMode);
this.getNextLineIndent = function(state, line, tab) {
var indent = this.$getIndent(line);
var startingIndent = indent;
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;

View file

@ -38,17 +38,17 @@
define(function(require, exports, module) {
var oop = require("../lib/oop");
var TextMode = require("./text").Mode;
var XmlMode = require("./xml").Mode;
var JavaScriptMode = require("./javascript").Mode;
var CssMode = require("./css").Mode;
var Tokenizer = require("../tokenizer").Tokenizer;
var ColdfusionHighlightRules = require("./coldfusion_highlight_rules").ColdfusionHighlightRules;
var XmlBehaviour = require("./behaviour/xml").XmlBehaviour;
var Mode = function() {
XmlMode.call(this);
var highlighter = new ColdfusionHighlightRules();
this.$tokenizer = new Tokenizer(highlighter.getRules());
this.$behaviour = new XmlBehaviour();
this.$embeds = highlighter.getEmbeds();
this.createModeDelegates({
@ -56,24 +56,14 @@ var Mode = function() {
"css-": CssMode
});
};
oop.inherits(Mode, TextMode);
oop.inherits(Mode, XmlMode);
(function() {
this.foldingRules = "xml";
this.toggleCommentLines = function(state, doc, startRow, endRow) {
return 0;
};
this.getNextLineIndent = function(state, line, tab) {
return this.$getIndent(line);
};
this.checkOutdent = function(state, line, input) {
return false;
};
}).call(Mode.prototype);
exports.Mode = Mode;

View file

@ -41,76 +41,12 @@ var oop = require("../lib/oop");
var CssHighlightRules = require("./css_highlight_rules").CssHighlightRules;
var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules;
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
var xml_util = require("./xml_util");
var ColdfusionHighlightRules = function() {
// regexp must not have capturing parentheses
// regexps are ordered -> the first match is used
function string(state) {
return [{
token : "string",
regex : '".*?"'
}, {
token : "string", // multi line string start
merge : true,
regex : '["].*$',
next : state + "-qqstring"
}, {
token : "string",
regex : "'.*?'"
}, {
token : "string", // multi line string start
merge : true,
regex : "['].*$",
next : state + "-qstring"
}]
}
function multiLineString(quote, state) {
return [{
token : "string",
merge : true,
regex : ".*" + quote,
next : state
}, {
token : "string",
merge : true,
regex : '.+'
}]
}
function tag(states, name, nextState) {
states[name] = [{
token : "text",
regex : "\\s+"
}, {
token : "meta.tag",
regex : "[-_a-zA-Z0-9:]+",
next : name + "-attribute-list"
}, {
token: "empty",
regex: "",
next : name + "-attribute-list"
}];
states[name + "-qstring"] = multiLineString("'", name);
states[name + "-qqstring"] = multiLineString("\"", name);
states[name + "-attribute-list"] = [{
token : "text",
regex : ">",
next : nextState
}, {
token : "entity.other.attribute-name",
regex : "[-_a-zA-Z0-9:]+"
}, {
token : "constant.numeric", // float
regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
}, {
token : "text",
regex : "\\s+"
}].concat(string(name));
};
this.$rules = {
start : [ {
@ -127,15 +63,15 @@ var ColdfusionHighlightRules = function() {
regex : "<\\!--",
next : "comment"
}, {
token : "text",
token : "meta.tag",
regex : "<(?=\s*script)",
next : "script"
}, {
token : "text",
token : "meta.tag",
regex : "<(?=\s*style)",
next : "css"
}, {
token : "text", // opening tag
token : "meta.tag", // opening tag
regex : "<\\/?",
next : "tag"
}, {
@ -171,22 +107,22 @@ var ColdfusionHighlightRules = function() {
} ]
};
tag(this.$rules, "tag", "start");
tag(this.$rules, "css", "css-start");
tag(this.$rules, "script", "js-start");
xml_util.tag(this.$rules, "tag", "start");
xml_util.tag(this.$rules, "css", "css-start");
xml_util.tag(this.$rules, "script", "js-start");
this.embedRules(JavaScriptHighlightRules, "js-", [{
token: "comment",
regex: "\\/\\/.*(?=<\\/script>)",
next: "tag"
}, {
token: "text",
token: "meta.tag",
regex: "<\\/(?=script)",
next: "tag"
}]);
this.embedRules(CssHighlightRules, "css-", [{
token: "text",
token: "meta.tag",
regex: "<\\/(?=style)",
next: "tag"
}]);

View file

@ -6,24 +6,23 @@ var Tokenizer = require("../tokenizer").Tokenizer;
var CSharpHighlightRules = require("./csharp_highlight_rules").CSharpHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
var Mode = function() {
this.$tokenizer = new Tokenizer(new CSharpHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.$behaviour = new CstyleBehaviour();
this.foldingRules = new CStyleFoldMode();
};
oop.inherits(Mode, TextMode);
(function() {
this.foldingRules = "cStyle";
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;

View file

@ -43,10 +43,12 @@ var Tokenizer = require("../tokenizer").Tokenizer;
var CssHighlightRules = require("./css_highlight_rules").CssHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var WorkerClient = require("../worker/worker_client").WorkerClient;
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
var Mode = function() {
this.$tokenizer = new Tokenizer(new CssHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.foldingRules = new CStyleFoldMode();
};
oop.inherits(Mode, TextMode);

View file

@ -0,0 +1,106 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Ajax.org Code Editor (ACE).
*
* The Initial Developer of the Original Code is
* Ajax.org B.V.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Fabian Jakobs <fabian AT ajax DOT org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
define(function(require, exports, module) {
var oop = require("../../lib/oop");
var Range = require("../../range").Range;
var BaseFoldMode = require("./fold_mode").FoldMode;
var FoldMode = exports.FoldMode = function() {};
oop.inherits(FoldMode, BaseFoldMode);
(function() {
this.foldingStartMarker = /(\{|\[)[^\}\]]*$|^\s*(\/\*)/;
this.foldingStopMarker = /^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/;
this.getFoldWidgetRange = function(session, row) {
var line = session.getLine(row);
var match = line.match(this.foldingStartMarker);
if (match) {
var i = match.index;
if (match[2])
return session.getCommentFoldRange(row, i + match[0].length);
var start = {row: row, column: i+1};
var end = session.$findClosingBracket(match[1], start);
if (end) {
var fw = session.foldWidgets[end.row];
if (fw == null)
fw = this.getFoldWidget(session, end.row);
if (fw == "start"){
end.row --;
end.column = session.getLine(end.row).length;
}
} else {
end = {row: session.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 session.getCommentFoldRange(row, i);
var end = {row: row, column: i};
var start = session.$findOpeningBracket(match[1], end);
if (start) {
start.column++;
end.column--;
} else {
start = {
row: 0,
column: session.getLine(0).length
};
}
return Range.fromPoints(start, end);
}
};
}).call(FoldMode.prototype);
});

View file

@ -0,0 +1,108 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Ajax.org Code Editor (ACE).
*
* The Initial Developer of the Original Code is
* Ajax.org B.V.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Fabian Jakobs <fabian AT ajax DOT org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
define(function(require, exports, module) {
var Range = require("../../range").Range;
var FoldMode = exports.FoldMode = function() {};
(function() {
this.FOO = 12;
this.foldingStartMarker = null;
this.foldingStopMarker = null;
this.getFoldWidget = function(session, row) {
if (this.foldingStartMarker) {
if (this.foldingStopMarker)
return this.$testBoth(session, row);
else
return this.$testStart(session, row);
}
else
return "";
};
this.getFoldWidgetRange = function(session, row) {
return null;
};
this.indentationBlock = function(session, row) {
var re = /^\s*/;
var startRow = row, endRow = row;
var line = session.getLine(row);
var startColumn = line.length - 1;
var startLevel = line.match(re)[0].length;
while (line = session.getLine(++row)) {
var level = line.match(re)[0].length;
if (level == line.length)
continue;
if (level <= startLevel)
break;
endRow = row;
}
if (endRow > startRow) {
var endColumn = session.getLine(endRow).length;
return new Range(startRow, startColumn, endRow, endColumn);
}
};
this.$testStart = function(session, row) {
if(this.foldingStartMarker.test(session.getLine(row)))
return "start";
return "";
};
this.$testBoth = function(session, row) {
var line = session.getLine(row);
if(this.foldingStartMarker.test(line))
return "start";
if(this.foldingStopMarker.test(line))
return "end";
return "";
};
}).call(FoldMode.prototype);
});

View file

@ -0,0 +1,53 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Ajax.org Code Editor (ACE).
*
* The Initial Developer of the Original Code is
* Ajax.org B.V.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Fabian Jakobs <fabian AT ajax DOT org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
define(function(require, exports, module) {
var oop = require("../../lib/oop");
var BaseFoldMode = require("./fold_mode").FoldMode;
var FoldMode = exports.FoldMode = function() {};
oop.inherits(FoldMode, BaseFoldMode);
(function() {
this.foldingStartMarker = /\:(:?\s*)?(:?#.*)?$/;
this.getFoldWidgetRange = BaseFoldMode.prototype.indentationBlock;
}).call(FoldMode.prototype);
});

176
lib/ace/mode/folding/xml.js Normal file
View file

@ -0,0 +1,176 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Ajax.org Code Editor (ACE).
*
* The Initial Developer of the Original Code is
* Ajax.org B.V.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Fabian Jakobs <fabian AT ajax DOT org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
define(function(require, exports, module) {
var oop = require("../../lib/oop");
var Range = require("../../range").Range;
var BaseFoldMode = require("./fold_mode").FoldMode;
var TokenIterator = require("../../token_iterator").TokenIterator;
var FoldMode = exports.FoldMode = function(voidElements) {
BaseFoldMode.call(this);
this.voidElements = voidElements || {};
};
oop.inherits(FoldMode, BaseFoldMode);
(function() {
this.getFoldWidget = function(session, row) {
var tags = session.getTokens(row, row)[0].tokens
.filter(function(token) {
return token.type === "meta.tag";
})
.map(function(token) {
return token.value;
}).
join("")
.trim()
.replace(/^<|>$|\s+/g, "")
.split("><");
var fold = tags[0];
if (!fold || this.voidElements[fold])
return;
if (fold.charAt(0) == "/")
return "end";
if (tags.indexOf("/" + fold) !== -1)
return;
return "start";
};
this.getFoldWidgetRange = function(session, row) {
var start, end;
var stack = [];
var iterator = new TokenIterator(session, row, 0);
var step = "stepForward";
var isBack = false;
// http://dev.w3.org/html5/spec/syntax.html#optional-tags
// TODO
// var optionalTags = {
// "html": 1,
// "head": 1,
// "body": 1,
// "li": 1,
// "dt": 1,
// "dd": 1,
// "p": 1,
// "rt": 1,
// "rp": 1,
// "optgroup": 1,
// "option": 1,
// "colgroup": 1,
// "thead": 1,
// "tbody": 1,
// "tfoot": 1,
// "tr": 1,
// "td": 1,
// "th": 1
// };
// limited XML parsing to find matching tag
do {
var token = iterator.getCurrentToken();
var value = token.value.trim();
if (token && token.type == "meta.tag" && token.value !== ">") {
var tagName = value.replace(/^[<\s]*|[\s*>]$/g, "");
if (this.voidElements[tagName])
continue;
if (!start) {
if (tagName.charAt(0) == "/") {
tagName = tagName.slice(1);
step = "stepBackward";
isBack = true;
}
start = {
row: row,
column: iterator.getCurrentTokenColumn() + (isBack ? 0 : value.length + 1)
};
// console.log("push", tagName)
stack.push(tagName);
}
else {
var close;
if (tagName.charAt(0) == "/") {
tagName = tagName.slice(1);
close = !isBack;
}
else
close = isBack;
if (close) {
if (stack[stack.length-1] == tagName) {
// console.log("pop", tagName)
stack.pop();
if (stack.length === 0) {
end = {
row: iterator.getCurrentTokenRow(),
column: iterator.getCurrentTokenColumn() + (isBack ? value.length : 0)
};
if (isBack)
return Range.fromPoints(end, start);
else
return Range.fromPoints(start, end);
}
}
else {
console.error("unmatched tags!", tagName, stack);
}
}
else {
// console.log("push", tagName)
stack.push(tagName);
}
}
}
} while(token = iterator[step]());
};
}).call(FoldMode.prototype);
});

View file

@ -4,20 +4,15 @@ var oop = require("../lib/oop");
var JavaScriptMode = require("./javascript").Mode;
var Tokenizer = require("../tokenizer").Tokenizer;
var GroovyHighlightRules = require("./groovy_highlight_rules").GroovyHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
var Mode = function() {
JavaScriptMode.call(this);
this.$tokenizer = new Tokenizer(new GroovyHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.$behaviour = new CstyleBehaviour();
};
oop.inherits(Mode, JavaScriptMode);
(function() {
this.foldingRules = "cStyle";
this.createWorker = function(session) {
return null;
};

View file

@ -6,18 +6,18 @@ var Tokenizer = require("../tokenizer").Tokenizer;
var HaxeHighlightRules = require("./haxe_highlight_rules").HaxeHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
var Mode = function() {
this.$tokenizer = new Tokenizer(new HaxeHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.$behaviour = new CstyleBehaviour();
this.foldingRules = new CStyleFoldMode();
};
oop.inherits(Mode, TextMode);
(function() {
this.foldingRules = "cStyle";
this.getNextLineIndent = function(state, line, tab) {
var indent = this.$getIndent(line);

View file

@ -44,6 +44,7 @@ var CssMode = require("./css").Mode;
var Tokenizer = require("../tokenizer").Tokenizer;
var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules;
var XmlBehaviour = require("./behaviour/xml").XmlBehaviour;
var XmlFoldMode = require("./folding/xml").FoldMode;
var Mode = function() {
var highlighter = new HtmlHighlightRules();
@ -55,12 +56,30 @@ var Mode = function() {
"js-": JavaScriptMode,
"css-": CssMode
});
this.foldingRules = new XmlFoldMode({
"area": 1,
"base": 1,
"br": 1,
"col": 1,
"command": 1,
"embed": 1,
"hr": 1,
"img": 1,
"input": 1,
"keygen": 1,
"link": 1,
"meta": 1,
"param": 1,
"source": 1,
"track": 1,
"wbr": 1
});
};
oop.inherits(Mode, TextMode);
(function() {
this.foldingRules = "xml";
this.toggleCommentLines = function(state, doc, startRow, endRow) {
return 0;

View file

@ -4,20 +4,16 @@ var oop = require("../lib/oop");
var JavaScriptMode = require("./javascript").Mode;
var Tokenizer = require("../tokenizer").Tokenizer;
var JavaHighlightRules = require("./java_highlight_rules").JavaHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
var Mode = function() {
JavaScriptMode.call(this);
this.$tokenizer = new Tokenizer(new JavaHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.$behaviour = new CstyleBehaviour();
};
oop.inherits(Mode, JavaScriptMode);
(function() {
this.foldingRules = "cStyle";
this.createWorker = function(session) {
return null;
};

View file

@ -45,17 +45,18 @@ var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutd
var Range = require("../range").Range;
var WorkerClient = require("../worker/worker_client").WorkerClient;
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
var Mode = function() {
this.$tokenizer = new Tokenizer(new JavaScriptHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.$behaviour = new CstyleBehaviour();
this.foldingRules = new CStyleFoldMode();
};
oop.inherits(Mode, TextMode);
(function() {
this.foldingRules = "cStyle";
this.toggleCommentLines = function(state, doc, startRow, endRow) {
var outdent = true;

View file

@ -43,18 +43,18 @@ var Tokenizer = require("../tokenizer").Tokenizer;
var HighlightRules = require("./json_highlight_rules").JsonHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
var Mode = function() {
this.$tokenizer = new Tokenizer(new HighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.$behaviour = new CstyleBehaviour();
this.foldingRules = new CStyleFoldMode();
};
oop.inherits(Mode, TextMode);
(function() {
this.foldingRules = "cStyle";
this.getNextLineIndent = function(state, line, tab) {
var indent = this.$getIndent(line);

View file

@ -43,17 +43,17 @@ var Tokenizer = require("../tokenizer").Tokenizer;
var PerlHighlightRules = require("./perl_highlight_rules").PerlHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var Range = require("../range").Range;
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
var Mode = function() {
this.$tokenizer = new Tokenizer(new PerlHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.foldingRules = new CStyleFoldMode();
};
oop.inherits(Mode, TextMode);
(function() {
this.foldingRules = "cStyle";
this.toggleCommentLines = function(state, doc, startRow, endRow) {
var outdent = true;
var re = /^(\s*)#/;

View file

@ -44,18 +44,18 @@ var PhpHighlightRules = require("./php_highlight_rules").PhpHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var Range = require("../range").Range;
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
var Mode = function() {
this.$tokenizer = new Tokenizer(new PhpHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.$behaviour = new CstyleBehaviour();
this.foldingRules = new CStyleFoldMode();
};
oop.inherits(Mode, TextMode);
(function() {
this.foldingRules = "cStyle";
this.toggleCommentLines = function(state, doc, startRow, endRow) {
var outdent = true;
var re = /^(\s*)#/;

View file

@ -6,18 +6,18 @@ var Tokenizer = require("../tokenizer").Tokenizer;
var PowershellHighlightRules = require("./powershell_highlight_rules").PowershellHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
var Mode = function() {
this.$tokenizer = new Tokenizer(new PowershellHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.$behaviour = new CstyleBehaviour();
this.foldingRules = new CStyleFoldMode();
};
oop.inherits(Mode, TextMode);
(function() {
this.foldingRules = "cStyle";
this.getNextLineIndent = function(state, line, tab) {
var indent = this.$getIndent(line);

View file

@ -42,24 +42,19 @@ var oop = require("../lib/oop");
var TextMode = require("./text").Mode;
var Tokenizer = require("../tokenizer").Tokenizer;
var PythonHighlightRules = require("./python_highlight_rules").PythonHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var PythonFoldMode = require("./folding/python").FoldMode;
var Range = require("../range").Range;
var Mode = function() {
this.$tokenizer = new Tokenizer(new PythonHighlightRules().getRules());
this.foldingRules = new PythonFoldMode();
};
oop.inherits(Mode, TextMode);
(function() {
this.foldingRules = {
foldingStartMarker: /\:(:?\s*)?(:?#.*)?$/,
getFoldWidgetRange: "indentationBlock"
};
this.toggleCommentLines = function(state, doc, startRow, endRow) {
var outdent = true;
var outentedRows = [];
var re = /^(\s*)#/;
for (var i=startRow; i<= endRow; i++) {
@ -91,7 +86,6 @@ oop.inherits(Mode, TextMode);
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;

View file

@ -45,11 +45,13 @@ var scadHighlightRules = require("./scad_highlight_rules").scadHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var Range = require("../range").Range;
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
var Mode = function() {
this.$tokenizer = new Tokenizer(new scadHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.$behaviour = new CstyleBehaviour();
this.foldingRules = new CStyleFoldMode();
};
oop.inherits(Mode, TextMode);
@ -57,7 +59,6 @@ oop.inherits(Mode, TextMode);
this.toggleCommentLines = function(state, doc, startRow, endRow) {
var outdent = true;
var outentedRows = [];
var re = /^(\s*)\/\//;
for (var i=startRow; i<= endRow; i++) {

View file

@ -4,20 +4,16 @@ var oop = require("../lib/oop");
var JavaScriptMode = require("./javascript").Mode;
var Tokenizer = require("../tokenizer").Tokenizer;
var ScalaHighlightRules = require("./scala_highlight_rules").ScalaHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
var Mode = function() {
JavaScriptMode.call(this);
this.$tokenizer = new Tokenizer(new ScalaHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.$behaviour = new CstyleBehaviour();
};
oop.inherits(Mode, JavaScriptMode);
(function() {
this.foldingRules = "cStyle";
this.createWorker = function(session) {
return null;
};

View file

@ -42,17 +42,17 @@ var TextMode = require("./text").Mode;
var Tokenizer = require("../tokenizer").Tokenizer;
var ScssHighlightRules = require("./scss_highlight_rules").ScssHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
var Mode = function() {
this.$tokenizer = new Tokenizer(new ScssHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.foldingRules = new CStyleFoldMode();
};
oop.inherits(Mode, TextMode);
(function() {
this.foldingRules = "cStyle";
this.getNextLineIndent = function(state, line, tab) {
var indent = this.$getIndent(line);

View file

@ -38,16 +38,16 @@
define(function(require, exports, module) {
var oop = require("../lib/oop");
var XmlMode = require("./text").Mode;
var XmlMode = require("./xml").Mode;
var JavaScriptMode = require("./javascript").Mode;
var Tokenizer = require("../tokenizer").Tokenizer;
var SvgHighlightRules = require("./svg_highlight_rules").SvgHighlightRules;
var XmlBehaviour = require("./behaviour/xml").XmlBehaviour;
var Mode = function() {
XmlMode.call(this);
this.highlighter = new SvgHighlightRules();
this.$tokenizer = new Tokenizer(this.highlighter.getRules());
this.$behaviour = new XmlBehaviour();
this.$embeds = this.highlighter.getEmbeds();
this.createModeDelegates({
@ -58,20 +58,11 @@ var Mode = function() {
oop.inherits(Mode, XmlMode);
(function() {
this.foldingRules = "xml";
this.toggleCommentLines = function(state, doc, startRow, endRow) {
return 0;
};
this.getNextLineIndent = function(state, line, tab) {
return this.$getIndent(line);
};
this.checkOutdent = function(state, line, input) {
return false;
};
}).call(Mode.prototype);

View file

@ -42,17 +42,18 @@ var TextMode = require("./text").Mode;
var Tokenizer = require("../tokenizer").Tokenizer;
var XmlHighlightRules = require("./xml_highlight_rules").XmlHighlightRules;
var XmlBehaviour = require("./behaviour/xml").XmlBehaviour;
var XmlFoldMode = require("./folding/xml").FoldMode;
var Mode = function() {
this.$tokenizer = new Tokenizer(new XmlHighlightRules().getRules());
this.$behaviour = new XmlBehaviour();
this.foldingRules = new XmlFoldMode();
};
oop.inherits(Mode, TextMode);
(function() {
this.foldingRules = "xml";
this.getNextLineIndent = function(state, line, tab) {
return this.$getIndent(line);