From d22626771b3bfa5432f3182bd12e6e66628ff096 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 21 Sep 2013 20:44:19 +0400 Subject: [PATCH] improve csharp folding --- lib/ace/mode/csharp.js | 2 +- lib/ace/mode/csharp_highlight_rules.js | 3 + lib/ace/mode/folding/csharp.js | 138 +++++++++++++++++++++++++ 3 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 lib/ace/mode/folding/csharp.js diff --git a/lib/ace/mode/csharp.js b/lib/ace/mode/csharp.js index 66644b45..0ef0101c 100644 --- a/lib/ace/mode/csharp.js +++ b/lib/ace/mode/csharp.js @@ -7,7 +7,7 @@ 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 CStyleFoldMode = require("./folding/csharp").FoldMode; var Mode = function() { var highlighter = new CSharpHighlightRules(); diff --git a/lib/ace/mode/csharp_highlight_rules.js b/lib/ace/mode/csharp_highlight_rules.js index c18be8ea..89cbc2d5 100644 --- a/lib/ace/mode/csharp_highlight_rules.js +++ b/lib/ace/mode/csharp_highlight_rules.js @@ -56,6 +56,9 @@ var CSharpHighlightRules = function() { }, { token : "keyword.operator", regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" + }, { + token : "keyword", + regex : "^\\s*#(if|else|elif|endif|define|undef|warning|error|line|region|endregion|pragma)" }, { token : "punctuation.operator", regex : "\\?|\\:|\\,|\\;|\\." diff --git a/lib/ace/mode/folding/csharp.js b/lib/ace/mode/folding/csharp.js new file mode 100644 index 00000000..c4507534 --- /dev/null +++ b/lib/ace/mode/folding/csharp.js @@ -0,0 +1,138 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * 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 + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * 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 + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Range = require("../../range").Range; +var CFoldMode = require("./cstyle").FoldMode; + +var FoldMode = exports.FoldMode = function(commentRegex) { + if (commentRegex) { + this.foldingStartMarker = new RegExp( + this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start) + ); + this.foldingStopMarker = new RegExp( + this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end) + ); + } +}; +oop.inherits(FoldMode, CFoldMode); + +(function() { + this.usingRe = /^\s*using \S/; + + this.getFoldWidgetRangeBase = this.getFoldWidgetRange; + this.getFoldWidgetBase = this.getFoldWidget; + + this.getFoldWidget = function(session, foldStyle, row) { + var fw = this.getFoldWidgetBase(session, foldStyle, row); + if (!fw) { + var line = session.getLine(row); + if (/^\s*#region\b/.test(line)) + return "start"; + var usingRe = this.usingRe; + if (usingRe.test(line)) { + var prev = session.getLine(row - 1); + var next = session.getLine(row + 1); + if (!usingRe.test(prev) && usingRe.test(next)) + return "start" + } + } + return fw; + }; + + this.getFoldWidgetRange = function(session, foldStyle, row) { + var range = this.getFoldWidgetRangeBase(session, foldStyle, row); + if (range) + return range; + + var line = session.getLine(row); + if (this.usingRe.test(line)) + return this.getUsingStatementBlock(session, line, row); + + if (/^\s*#region\b/.test(line)) + return this.getRegionBlock(session, line, row); + }; + + this.getUsingStatementBlock = function(session, line, row) { + var startColumn = line.match(this.usingRe)[0].length - 1; + var maxRow = session.getLength(); + var startRow = row; + var endRow = row; + + while (++row < maxRow) { + line = session.getLine(row); + if (/^\s*$/.test(line)) + continue; + if (!this.usingRe.test(line)) + break; + + endRow = row; + } + + if (endRow > startRow) { + var endColumn = session.getLine(endRow).length; + return new Range(startRow, startColumn, endRow, endColumn); + } + }; + + this.getRegionBlock = function(session, line, row) { + var startColumn = line.search(/\s*$/); + var maxRow = session.getLength(); + var startRow = row; + + var re = /^\s*#(end)?region\b/ + var depth = 1 + while (++row < maxRow) { + line = session.getLine(row); + var m = re.exec(line); + if (!m) + continue; + if (m[1]) + depth--; + else + depth++; + + if (!depth) + break; + } + + var endRow = row; + if (endRow > startRow) { + var endColumn = line.search(/\S/); + return new Range(startRow, startColumn, endRow, endColumn); + } + }; + +}).call(FoldMode.prototype); + +});