From 6c5ab388cf123d771db754ffd8075304495c503b Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 6 Mar 2013 20:00:59 +0400 Subject: [PATCH 01/11] fix lua comment folding --- lib/ace/mode/folding/lua.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ace/mode/folding/lua.js b/lib/ace/mode/folding/lua.js index a7d3205c..42a3072e 100644 --- a/lib/ace/mode/folding/lua.js +++ b/lib/ace/mode/folding/lua.js @@ -60,7 +60,7 @@ oop.inherits(FoldMode, BaseFoldMode); return "start"; } else if (match[2]) { var type = session.bgTokenizer.getState(row) || ""; - if (type.indexOf("comment") != -1 || type.indexOf("string") != -1) + if (type[0] == "bracketedComment" || type[0] == "bracketedString") return "start"; } else { return "start"; @@ -75,7 +75,7 @@ oop.inherits(FoldMode, BaseFoldMode); return "end"; } else if (match[0][0] === "]") { var type = session.bgTokenizer.getState(row - 1) || ""; - if (type.indexOf("comment") != -1 || type.indexOf("string") != -1) + if (type[0] == "bracketedComment" || type[0] == "bracketedString") return "end"; } else return "end"; From bc7d8a2ab2b28c16b01adda6c16d0b11bd97cfc7 Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 6 Mar 2013 20:02:17 +0400 Subject: [PATCH 02/11] make createSplitterRegexp more robust --- lib/ace/tokenizer.js | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/ace/tokenizer.js b/lib/ace/tokenizer.js index 6ed271b1..f7f7f02e 100644 --- a/lib/ace/tokenizer.js +++ b/lib/ace/tokenizer.js @@ -93,7 +93,7 @@ var Tokenizer = function(rules) { matchcount = 1; adjustedregex = this.removeCapturingGroups(rule.regex); } - if (!rule.splitRegex) + if (!rule.splitRegex && typeof rule.token != "string") rule.splitRegex = this.createSplitterRegexp(rule.regex, flag); } @@ -139,7 +139,34 @@ var Tokenizer = function(rules) { }; this.createSplitterRegexp = function(src, flag) { - src = src.replace(/\(\?=([^()]|\\.|\(([^()]|\\.)*?\))*\)(?=\)*$)/, ""); + if (src.indexOf("(?=") != -1) { + var stack = 0; + var inChClass = false; + var lastCapture = {}; + src.replace(/(\\.)|(\((?:\?[=!])?)|(\))|([])/g, function( + m, esc, parenOpen, parenClose, square, index + ) { + if (inChClass) { + inChClass = square != "]"; + } else if (square) { + inChClass = true; + } else if (parenClose) { + if (stack == lastCapture.stack) + lastCapture.end = index+1 + stack--; + } else if (parenOpen) { + stack++; + if (parenOpen.length != 1) { + lastCapture.stack = stack + lastCapture.start = index; + } + } + return m; + }); + + if (lastCapture.end != null && /^\)*$/.test(src.substr(lastCapture.end))) + src = src.substring(0, lastCapture.start) + src.substr(lastCapture.end); + } return new RegExp(src, (flag||"").replace("g", "")); }; From 2fc8ffcc38efddd94cfdde6d4b7e7470da1f0777 Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 6 Mar 2013 20:04:54 +0400 Subject: [PATCH 03/11] add highlighting for LogicBlox --- demo/kitchen-sink/doclist.js | 1 + demo/kitchen-sink/docs/logicblox.logic | 16 +++ demo/kitchen-sink/modelist.js | 1 + lib/ace/mode/logicblox.js | 55 +++++++++ lib/ace/mode/logicblox_highlight_rules.js | 131 ++++++++++++++++++++++ 5 files changed, 204 insertions(+) create mode 100644 demo/kitchen-sink/docs/logicblox.logic create mode 100644 lib/ace/mode/logicblox.js create mode 100644 lib/ace/mode/logicblox_highlight_rules.js diff --git a/demo/kitchen-sink/doclist.js b/demo/kitchen-sink/doclist.js index a47c00e6..0a066afe 100644 --- a/demo/kitchen-sink/doclist.js +++ b/demo/kitchen-sink/doclist.js @@ -93,6 +93,7 @@ var docs = { "docs/lsl.lsl": "LSL", "docs/scheme.scm": "Scheme", "docs/liquid.liquid": "Liquid", + "docs/logicblox.logic": "LogicBlox", "docs/lua.lua": "Lua", "docs/lucene.lucene": "Lucene", "docs/luapage.lp": "LuaPage", diff --git a/demo/kitchen-sink/docs/logicblox.logic b/demo/kitchen-sink/docs/logicblox.logic new file mode 100644 index 00000000..910862d7 --- /dev/null +++ b/demo/kitchen-sink/docs/logicblox.logic @@ -0,0 +1,16 @@ +// ancestors +parentof("douglas", "john"). +parentof("john", "bob"). +parentof("bob", "ebbon"). + +parentof("douglas", "jane"). +parentof("jane", "jan"). + +ancestorof(A, B) <- parentof(A, B). +ancestorof(A, C) <- ancestorof(A, B), parentof(B,C). + +grandparentof(A, B) <- parentof(A, C), parentof(C, B). + +cousins(A,B) <- grandparentof(C,A), grandparentof(C,B). + +parentof[`arg](A, B) -> int[32](A), !string(B). \ No newline at end of file diff --git a/demo/kitchen-sink/modelist.js b/demo/kitchen-sink/modelist.js index 695a325f..1291ce66 100644 --- a/demo/kitchen-sink/modelist.js +++ b/demo/kitchen-sink/modelist.js @@ -65,6 +65,7 @@ var modesByName = { lisp: ["Lisp" , "lisp"], scheme: ["Scheme" , "scm|rkt"], liquid: ["Liquid" , "liquid"], + logicblox: ["LogicBlox" , "logic"], lua: ["Lua" , "lua"], luapage: ["LuaPage" , "lp"], // http://keplerproject.github.com/cgilua/manual.html#templates lucene: ["Lucene" , "lucene"], diff --git a/lib/ace/mode/logicblox.js b/lib/ace/mode/logicblox.js new file mode 100644 index 00000000..944533ad --- /dev/null +++ b/lib/ace/mode/logicblox.js @@ -0,0 +1,55 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, 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 TextMode = require("./text").Mode; +var Tokenizer = require("../tokenizer").Tokenizer; +var LogicBloxHighlightRules = require("./logicblox_highlight_rules").LogicBloxHighlightRules; +// TODO: pick appropriate fold mode +var FoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + var highlighter = new LogicBloxHighlightRules(); + this.foldingRules = new FoldMode(); + this.$tokenizer = new Tokenizer(highlighter.getRules()); +}; +oop.inherits(Mode, TextMode); + +(function() { + this.lineCommentStart = "//"; + this.blockComment = {start: "/*", end: "*/"}; + // Extra logic goes here. +}).call(Mode.prototype); + +exports.Mode = Mode; +}); \ No newline at end of file diff --git a/lib/ace/mode/logicblox_highlight_rules.js b/lib/ace/mode/logicblox_highlight_rules.js new file mode 100644 index 00000000..ea8573bb --- /dev/null +++ b/lib/ace/mode/logicblox_highlight_rules.js @@ -0,0 +1,131 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, 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 ***** */ + +/* THIS FILE WAS AUTOGENERATED FROM tool\LogicBlox.tmbundle\Syntaxes\LogicBlox.tmLanguage (UUID: 59bf5022-e261-453f-b1cb-9f9fa0712413) */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var LogicBloxHighlightRules = function() { + // regexp must not have capturing parentheses. Use (?:) instead. + // regexps are ordered -> the first match is used + + this.$rules = { start: + [ { token: 'comment.block', + regex: '/\\*', + push: + [ { token: 'comment.block', regex: '\\*/', next: 'pop' }, + { defaultToken: 'comment.block' } ], + //A block comment. + }, + { token: 'comment.single', + regex: '//.*', + //A single line comment. + }, + { token: 'constant.numeric', + regex: '\\d+', + //An integer constant. + }, + { token: 'constant.numeric', + regex: '\\d+(.\\d+){,1}[eE][+-]{,1}\\d+', + //Real numbers. + }, + { token: 'string', + regex: '"', + push: + [ { token: 'string', regex: '"', next: 'pop' }, + { defaultToken: 'string' } ], + //Strings + }, + { token: 'constant.language', + regex: '\\b(true|false)\\b', + //Boolean values. + }, + { token: 'entity.name.type.logicblox', + regex: '`[a-zA-Z_:]+(\\d|\\a)*\\b', + //LogicBlox Symbol + }, + { token: 'keyword.other', regex: '->', comment: 'Constraint' }, + { token: 'keyword.other', + regex: '-->', + //Level 1 Constraint + }, + { token: 'keyword.other', regex: '<-', comment: 'Rule' }, + { token: 'keyword.other', regex: '<--', comment: 'Level 1 Rule' }, + { token: 'keyword.other', regex: '\\.', comment: 'Terminator' }, + { token: 'keyword.other', regex: '!', comment: 'Negation' }, + { token: 'keyword.other', regex: ',', comment: 'Conjunction' }, + { token: 'keyword.other', regex: ';', comment: 'Disjunction' }, + { token: 'keyword.operator', + regex: '<=|>=|!=|<|>', + //Equality + }, + { token: 'keyword.other', regex: '@', comment: 'Equality' }, + { token: 'keyword.operator', + regex: '\\+|-|\\*|/', + //Arithmetic operations + }, + { token: 'keyword', regex: '::', comment: 'Colon colon' }, + { token: 'support.function', + regex: '\\b(agg\\s*<<)', + push: + [ { include: '$self' }, + { token: 'support.function', + regex: '>>', + next: 'pop' } ], + //Aggregations + }, + { token: 'storage.modifier', + regex: '\\b(lang:[\\w:]*)', + //All the lang system predicates + }, + { token: [ 'storage.type', 'text' ], + regex: '(export|sealed|clauses|block|alias)\\s*\\((?=`)', + //Module keywords + }, + { token: 'entity.name', + regex: '[a-zA-Z_][a-zA-Z_0-9:]*(@prev|@init|@final)?(?=(\\(|\\[))', + //A predicate name. + }, + { token: 'variable.parameter', + regex: '([a-zA-Z][a-zA-Z_0-9]*|_)\\s*(?=(,|\\.|<-|->|\\)|\\]|=))', + //A variable to a functional predicate. + } ] } + + this.normalizeRules(); +}; + +oop.inherits(LogicBloxHighlightRules, TextHighlightRules); + +exports.LogicBloxHighlightRules = LogicBloxHighlightRules; +}); \ No newline at end of file From 5d6bc3a75d3857231cb4bf91e4c96856f68232af Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 6 Mar 2013 20:31:24 +0400 Subject: [PATCH 04/11] add highlighting and folding for POD documentation --- demo/kitchen-sink/docs/perl.pl | 5 +++++ lib/ace/mode/_test/tokens_perl.json | 13 +++++++++++++ lib/ace/mode/folding/cstyle.js | 11 ++++++++++- lib/ace/mode/perl.js | 7 ++++++- lib/ace/mode/perl_highlight_rules.js | 14 ++++++++++++++ lib/ace/mode/powershell.js | 2 +- 6 files changed, 49 insertions(+), 3 deletions(-) diff --git a/demo/kitchen-sink/docs/perl.pl b/demo/kitchen-sink/docs/perl.pl index 01178e1c..d6a332e2 100644 --- a/demo/kitchen-sink/docs/perl.pl +++ b/demo/kitchen-sink/docs/perl.pl @@ -1,4 +1,8 @@ #!/usr/bin/perl +=begin + perl example code for Ace +=cut + use strict; use warnings; my $num_primes = 0; @@ -30,3 +34,4 @@ for my $p (0 .. ($num_primes-1)) print $primes[$p], ", "; } print "\n"; + diff --git a/lib/ace/mode/_test/tokens_perl.json b/lib/ace/mode/_test/tokens_perl.json index 9822a8bd..30bb39c6 100644 --- a/lib/ace/mode/_test/tokens_perl.json +++ b/lib/ace/mode/_test/tokens_perl.json @@ -1,6 +1,17 @@ [[ "start", ["comment","#!/usr/bin/perl"] +],[ + "block_comment", + ["comment.doc","=begin"] +],[ + "block_comment", + ["comment.doc"," perl example code for Ace"] +],[ + "start", + ["comment.doc","=cut"] +],[ + "start" ],[ "start", ["keyword","use"], @@ -211,4 +222,6 @@ ["text",";"] ],[ "start" +],[ + "start" ]] \ No newline at end of file diff --git a/lib/ace/mode/folding/cstyle.js b/lib/ace/mode/folding/cstyle.js index f3ee25ea..8be20d27 100644 --- a/lib/ace/mode/folding/cstyle.js +++ b/lib/ace/mode/folding/cstyle.js @@ -35,7 +35,16 @@ var oop = require("../../lib/oop"); var Range = require("../../range").Range; var BaseFoldMode = require("./fold_mode").FoldMode; -var FoldMode = exports.FoldMode = function() {}; +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, BaseFoldMode); (function() { diff --git a/lib/ace/mode/perl.js b/lib/ace/mode/perl.js index de0ed19f..ff8eaa18 100644 --- a/lib/ace/mode/perl.js +++ b/lib/ace/mode/perl.js @@ -42,13 +42,18 @@ var CStyleFoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { this.$tokenizer = new Tokenizer(new PerlHighlightRules().getRules()); this.$outdent = new MatchingBraceOutdent(); - this.foldingRules = new CStyleFoldMode(); + this.foldingRules = new CStyleFoldMode({start: "^=(begin|item)\\b", end: "^=(cut)\\b"}); }; oop.inherits(Mode, TextMode); (function() { this.lineCommentStart = "#"; + this.blockComment = [ + {start: "=begin", end: "=cut"}, + {start: "=item", end: "=cut"} + ]; + this.getNextLineIndent = function(state, line, tab) { var indent = this.$getIndent(line); diff --git a/lib/ace/mode/perl_highlight_rules.js b/lib/ace/mode/perl_highlight_rules.js index 98586bb7..046ecb7b 100644 --- a/lib/ace/mode/perl_highlight_rules.js +++ b/lib/ace/mode/perl_highlight_rules.js @@ -82,6 +82,10 @@ var PerlHighlightRules = function() { { token : "comment", regex : "#.*$" + }, { + token : "comment.doc", + regex : "^=(?:begin|item)\\b", + next : "block_comment" }, { token : "string.regexp", regex : "[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)" @@ -141,6 +145,16 @@ var PerlHighlightRules = function() { token : "string", regex : '.+' } + ], + "block_comment": [ + { + token: "comment.doc", + regex: "^=cut\\b", + next: "start" + }, + { + defaultToken: "comment.doc" + } ] }; }; diff --git a/lib/ace/mode/powershell.js b/lib/ace/mode/powershell.js index db414c2e..b0c12eb7 100644 --- a/lib/ace/mode/powershell.js +++ b/lib/ace/mode/powershell.js @@ -13,7 +13,7 @@ var Mode = function() { this.$tokenizer = new Tokenizer(new PowershellHighlightRules().getRules()); this.$outdent = new MatchingBraceOutdent(); this.$behaviour = new CstyleBehaviour(); - this.foldingRules = new CStyleFoldMode(); + this.foldingRules = new CStyleFoldMode({start: "^\\s*(<#)", end: "^[#\\s]>\\s*$"}); }; oop.inherits(Mode, TextMode); From 49aa5a540914b4fc649d408dd4595fa2aea847c1 Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 12 Mar 2013 13:16:55 +0400 Subject: [PATCH 05/11] fix highlighting of LogicBlox numbers --- lib/ace/mode/logicblox_highlight_rules.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/ace/mode/logicblox_highlight_rules.js b/lib/ace/mode/logicblox_highlight_rules.js index ea8573bb..f9da2e02 100644 --- a/lib/ace/mode/logicblox_highlight_rules.js +++ b/lib/ace/mode/logicblox_highlight_rules.js @@ -53,12 +53,9 @@ var LogicBloxHighlightRules = function() { //A single line comment. }, { token: 'constant.numeric', - regex: '\\d+', + regex: '\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?', //An integer constant. - }, - { token: 'constant.numeric', - regex: '\\d+(.\\d+){,1}[eE][+-]{,1}\\d+', - //Real numbers. + //Or a Real number. }, { token: 'string', regex: '"', From 35c239d280173a3dad107460474fa19af707021d Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 12 Mar 2013 13:22:17 +0400 Subject: [PATCH 06/11] rename LogicBlox to LogicQL --- demo/kitchen-sink/doclist.js | 2 +- demo/kitchen-sink/docs/{logicblox.logic => logicql.logic} | 0 demo/kitchen-sink/modelist.js | 2 +- lib/ace/mode/{logicblox.js => logicql.js} | 4 ++-- ...icblox_highlight_rules.js => logicql_highlight_rules.js} | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) rename demo/kitchen-sink/docs/{logicblox.logic => logicql.logic} (100%) rename lib/ace/mode/{logicblox.js => logicql.js} (93%) rename lib/ace/mode/{logicblox_highlight_rules.js => logicql_highlight_rules.js} (96%) diff --git a/demo/kitchen-sink/doclist.js b/demo/kitchen-sink/doclist.js index 0a066afe..dbfb6f11 100644 --- a/demo/kitchen-sink/doclist.js +++ b/demo/kitchen-sink/doclist.js @@ -93,7 +93,7 @@ var docs = { "docs/lsl.lsl": "LSL", "docs/scheme.scm": "Scheme", "docs/liquid.liquid": "Liquid", - "docs/logicblox.logic": "LogicBlox", + "docs/logicql.logic": "LogicQL", "docs/lua.lua": "Lua", "docs/lucene.lucene": "Lucene", "docs/luapage.lp": "LuaPage", diff --git a/demo/kitchen-sink/docs/logicblox.logic b/demo/kitchen-sink/docs/logicql.logic similarity index 100% rename from demo/kitchen-sink/docs/logicblox.logic rename to demo/kitchen-sink/docs/logicql.logic diff --git a/demo/kitchen-sink/modelist.js b/demo/kitchen-sink/modelist.js index 1291ce66..929bb86c 100644 --- a/demo/kitchen-sink/modelist.js +++ b/demo/kitchen-sink/modelist.js @@ -65,7 +65,7 @@ var modesByName = { lisp: ["Lisp" , "lisp"], scheme: ["Scheme" , "scm|rkt"], liquid: ["Liquid" , "liquid"], - logicblox: ["LogicBlox" , "logic"], + logicql: ["LogicQL" , "logic"], lua: ["Lua" , "lua"], luapage: ["LuaPage" , "lp"], // http://keplerproject.github.com/cgilua/manual.html#templates lucene: ["Lucene" , "lucene"], diff --git a/lib/ace/mode/logicblox.js b/lib/ace/mode/logicql.js similarity index 93% rename from lib/ace/mode/logicblox.js rename to lib/ace/mode/logicql.js index 944533ad..bc0c16c7 100644 --- a/lib/ace/mode/logicblox.js +++ b/lib/ace/mode/logicql.js @@ -34,12 +34,12 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var Tokenizer = require("../tokenizer").Tokenizer; -var LogicBloxHighlightRules = require("./logicblox_highlight_rules").LogicBloxHighlightRules; +var LogicQLHighlightRules = require("./logicql_highlight_rules").LogicQLHighlightRules; // TODO: pick appropriate fold mode var FoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { - var highlighter = new LogicBloxHighlightRules(); + var highlighter = new LogicQLHighlightRules(); this.foldingRules = new FoldMode(); this.$tokenizer = new Tokenizer(highlighter.getRules()); }; diff --git a/lib/ace/mode/logicblox_highlight_rules.js b/lib/ace/mode/logicql_highlight_rules.js similarity index 96% rename from lib/ace/mode/logicblox_highlight_rules.js rename to lib/ace/mode/logicql_highlight_rules.js index f9da2e02..601c5bb2 100644 --- a/lib/ace/mode/logicblox_highlight_rules.js +++ b/lib/ace/mode/logicql_highlight_rules.js @@ -36,7 +36,7 @@ define(function(require, exports, module) { var oop = require("../lib/oop"); var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; -var LogicBloxHighlightRules = function() { +var LogicQLHighlightRules = function() { // regexp must not have capturing parentheses. Use (?:) instead. // regexps are ordered -> the first match is used @@ -122,7 +122,7 @@ var LogicBloxHighlightRules = function() { this.normalizeRules(); }; -oop.inherits(LogicBloxHighlightRules, TextHighlightRules); +oop.inherits(LogicQLHighlightRules, TextHighlightRules); -exports.LogicBloxHighlightRules = LogicBloxHighlightRules; +exports.LogicQLHighlightRules = LogicQLHighlightRules; }); \ No newline at end of file From 6d7e9e263d7a9ae3d95e81940ebadaafbd96e1c1 Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 12 Mar 2013 16:44:25 +0400 Subject: [PATCH 07/11] add demo for livescript --- demo/kitchen-sink/doclist.js | 1 + demo/kitchen-sink/docs/livescript.ls | 245 +++++++++++++++++++++++++ demo/kitchen-sink/modelist.js | 1 + lib/ace/mode/_test/text_livescript.txt | 1 + 4 files changed, 248 insertions(+) create mode 100644 demo/kitchen-sink/docs/livescript.ls create mode 100644 lib/ace/mode/_test/text_livescript.txt diff --git a/demo/kitchen-sink/doclist.js b/demo/kitchen-sink/doclist.js index dbfb6f11..dc685125 100644 --- a/demo/kitchen-sink/doclist.js +++ b/demo/kitchen-sink/doclist.js @@ -92,6 +92,7 @@ var docs = { "docs/lisp.lisp": "Lisp", "docs/lsl.lsl": "LSL", "docs/scheme.scm": "Scheme", + "docs/livescript.ls": "LiveScript", "docs/liquid.liquid": "Liquid", "docs/logicql.logic": "LogicQL", "docs/lua.lua": "Lua", diff --git a/demo/kitchen-sink/docs/livescript.ls b/demo/kitchen-sink/docs/livescript.ls new file mode 100644 index 00000000..ce082b4c --- /dev/null +++ b/demo/kitchen-sink/docs/livescript.ls @@ -0,0 +1,245 @@ +# Defines an editing mode for [Ace](http://ace.ajax.org). +# +# Open [test/ace.html](../test/ace.html) to test. + +require, exports, module <-! define \ace/mode/ls + +identifier = /(?![\d\s])[$\w\xAA-\uFFDC](?:(?!\s)[$\w\xAA-\uFFDC]|-[A-Za-z])*/$ + +exports.Mode = class LiveScriptMode extends require(\ace/mode/text)Mode + -> + @$tokenizer = + new (require \ace/tokenizer)Tokenizer LiveScriptMode.Rules + if require \ace/mode/matching_brace_outdent + @$outdent = new that.MatchingBraceOutdent + + indenter = // (? + : [({[=:] + | [-~]> + | \b (?: e(?:lse|xport) | d(?:o|efault) | t(?:ry|hen) | finally | + import (?:\s* all)? | const | var | + let | new | catch (?:\s* #identifier)? ) + ) \s* $ // + + getNextLineIndent: (state, line, tab) -> + indent = @$getIndent line + {tokens} = @$tokenizer.getLineTokens line, state + unless tokens.length and tokens[*-1]type is \comment + indent += tab if state is \start and indenter.test line + indent + + toggleCommentLines: (state, doc, startRow, endRow) -> + comment = /^(\s*)#/; range = new (require \ace/range)Range 0 0 0 0 + for i from startRow to endRow + if out = comment.test line = doc.getLine i + then line.=replace comment, \$1 + else line.=replace /^\s*/ \$&# + range.end.row = range.start.row = i + range.end.column = line.length + 1 + doc.replace range, line + 1 - out * 2 + + checkOutdent: (state, line, input) -> @$outdent?checkOutdent line, input + + autoOutdent: (state, doc, row) -> @$outdent?autoOutdent doc, row + +### Highlight Rules + +keywordend = /(?![$\w]|-[A-Za-z]|\s*:(?![:=]))/$ +stringfill = token: \string, regex: '.+' + +LiveScriptMode.Rules = + start: + * token: \keyword + regex: //(? + :t(?:h(?:is|row|en)|ry|ypeof!?) + |c(?:on(?:tinue|st)|a(?:se|tch)|lass) + |i(?:n(?:stanceof)?|mp(?:ort(?:\s+all)?|lements)|[fs]) + |d(?:e(?:fault|lete|bugger)|o) + |f(?:or(?:\s+own)?|inally|unction) + |s(?:uper|witch) + |e(?:lse|x(?:tends|port)|val) + |a(?:nd|rguments) + |n(?:ew|ot) + |un(?:less|til) + |w(?:hile|ith) + |o[fr]|return|break|let|var|loop + )//$ + keywordend + + * token: \constant.language + regex: '(?:true|false|yes|no|on|off|null|void|undefined)' + keywordend + + * token: \invalid.illegal + regex: '(? + :p(?:ackage|r(?:ivate|otected)|ublic) + |i(?:mplements|nterface) + |enum|static|yield + )' + keywordend + + * token: \language.support.class + regex: '(? + :R(?:e(?:gExp|ferenceError)|angeError) + |S(?:tring|yntaxError) + |E(?:rror|valError) + |Array|Boolean|Date|Function|Number|Object|TypeError|URIError + )' + keywordend + + * token: \language.support.function + regex: '(? + :is(?:NaN|Finite) + |parse(?:Int|Float) + |Math|JSON + |(?:en|de)codeURI(?:Component)? + )' + keywordend + + * token: \variable.language + regex: '(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)' + keywordend + + * token: \identifier + regex: identifier + /\s*:(?![:=])/$ + + * token: \variable + regex: identifier + + * token: \keyword.operator + regex: /(?:\.{3}|\s+\?)/$ + + * token: \keyword.variable + regex: /(?:@+|::|\.\.)/$ + next : \key + + * token: \keyword.operator + regex: /\.\s*/$ + next : \key + + * token: \string + regex: /\\\S[^\s,;)}\]]*/$ + + * token: \string.doc + regex: \''' + next : \qdoc + + * token: \string.doc + regex: \""" + next : \qqdoc + + * token: \string + regex: \' + next : \qstring + + * token: \string + regex: \" + next : \qqstring + + * token: \string + regex: \` + next : \js + + * token: \string + regex: '<\\[' + next : \words + + * token: \string.regex + regex: \// + next : \heregex + + * token: \comment.doc + regex: '/\\*' + next : \comment + + * token: \comment + regex: '#.*' + + * token: \string.regex + regex: // + /(?: [^ [ / \n \\ ]* + (?: (?: \\. + | \[ [^\]\n\\]* (?:\\.[^\]\n\\]*)* \] + ) [^ [ / \n \\ ]* + )* + )/ [gimy$]{0,4} + //$ + next : \key + + * token: \constant.numeric + regex: '(?:0x[\\da-fA-F][\\da-fA-F_]* + |(?:[2-9]|[12]\\d|3[0-6])r[\\da-zA-Z][\\da-zA-Z_]* + |(?:\\d[\\d_]*(?:\\.\\d[\\d_]*)?|\\.\\d[\\d_]*) + (?:e[+-]?\\d[\\d_]*)?[\\w$]*)' + + * token: \lparen + regex: '[({[]' + + * token: \rparen + regex: '[)}\\]]' + next : \key + + * token: \keyword.operator + regex: \\\S+ + + * token: \text + regex: \\\s+ + + heregex: + * token: \string.regex + regex: '.*?//[gimy$?]{0,4}' + next : \start + * token: \string.regex + regex: '\\s*#{' + * token: \comment.regex + regex: '\\s+(?:#.*)?' + * token: \string.regex + regex: '\\S+' + + key: + * token: \keyword.operator + regex: '[.?@!]+' + * token: \identifier + regex: identifier + next : \start + * token: \text + regex: '.' + next : \start + + comment: + * token: \comment.doc + regex: '.*?\\*/' + next : \start + * token: \comment.doc + regex: '.+' + + qdoc: + token: \string + regex: ".*?'''" + next : \key + stringfill + + qqdoc: + token: \string + regex: '.*?"""' + next : \key + stringfill + + qstring: + token: \string + regex: /[^\\']*(?:\\.[^\\']*)*'/$ + next : \key + stringfill + + qqstring: + token: \string + regex: /[^\\"]*(?:\\.[^\\"]*)*"/$ + next : \key + stringfill + + js: + token: \string + regex: /[^\\`]*(?:\\.[^\\`]*)*`/$ + next : \key + stringfill + + words: + token: \string + regex: '.*?\\]>' + next : \key + stringfill diff --git a/demo/kitchen-sink/modelist.js b/demo/kitchen-sink/modelist.js index 929bb86c..e9bc08e0 100644 --- a/demo/kitchen-sink/modelist.js +++ b/demo/kitchen-sink/modelist.js @@ -65,6 +65,7 @@ var modesByName = { lisp: ["Lisp" , "lisp"], scheme: ["Scheme" , "scm|rkt"], liquid: ["Liquid" , "liquid"], + livescript: ["LiveScript" , "ls"], logicql: ["LogicQL" , "logic"], lua: ["Lua" , "lua"], luapage: ["LuaPage" , "lp"], // http://keplerproject.github.com/cgilua/manual.html#templates diff --git a/lib/ace/mode/_test/text_livescript.txt b/lib/ace/mode/_test/text_livescript.txt new file mode 100644 index 00000000..308ec1db --- /dev/null +++ b/lib/ace/mode/_test/text_livescript.txt @@ -0,0 +1 @@ +# comment From 03b9591313f88fa5c2d55b58f4de8fdff638c15f Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 12 Mar 2013 16:46:30 +0400 Subject: [PATCH 08/11] cleanup $getIndent --- lib/ace/mode/matching_brace_outdent.js | 7 +------ lib/ace/mode/text.js | 7 +------ lib/ace/mode/xquery.js | 21 ++++++--------------- 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/lib/ace/mode/matching_brace_outdent.js b/lib/ace/mode/matching_brace_outdent.js index abdd7ed4..07f4829e 100644 --- a/lib/ace/mode/matching_brace_outdent.js +++ b/lib/ace/mode/matching_brace_outdent.js @@ -60,12 +60,7 @@ var MatchingBraceOutdent = function() {}; }; this.$getIndent = function(line) { - var match = line.match(/^(\s+)/); - if (match) { - return match[1]; - } - - return ""; + return line.match(/^\s*/)[0]; }; }).call(MatchingBraceOutdent.prototype); diff --git a/lib/ace/mode/text.js b/lib/ace/mode/text.js index edef0204..02cb466e 100644 --- a/lib/ace/mode/text.js +++ b/lib/ace/mode/text.js @@ -116,12 +116,7 @@ var Mode = function() { }; this.$getIndent = function(line) { - var match = line.match(/^(\s+)/); - if (match) { - return match[1]; - } - - return ""; + return line.match(/^\s*/)[0]; }; this.createWorker = function(session) { diff --git a/lib/ace/mode/xquery.js b/lib/ace/mode/xquery.js index 7dfdd5cf..e06478a4 100644 --- a/lib/ace/mode/xquery.js +++ b/lib/ace/mode/xquery.js @@ -50,22 +50,22 @@ oop.inherits(Mode, TextMode); (function() { this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - var match = line.match(/\s*(?:then|else|return|[{\(]|<\w+>)\s*$/); - if (match) - indent += tab; + var indent = this.$getIndent(line); + var match = line.match(/\s*(?:then|else|return|[{\(]|<\w+>)\s*$/); + if (match) + indent += tab; return indent; }; this.checkOutdent = function(state, line, input) { - if (! /^\s+$/.test(line)) + if (! /^\s+$/.test(line)) return false; return /^\s*[\}\)]/.test(input); }; this.autoOutdent = function(state, doc, row) { - var line = doc.getLine(row); + var line = doc.getLine(row); var match = line.match(/^(\s*[\}\)])/); if (!match) return 0; @@ -79,15 +79,6 @@ oop.inherits(Mode, TextMode); doc.replace(new Range(row, 0, row, column-1), indent); }; - this.$getIndent = function(line) { - var match = line.match(/^(\s+)/); - if (match) { - return match[1]; - } - - return ""; - }; - this.toggleCommentLines = function(state, doc, startRow, endRow) { var i, line; var outdent = true; From 137199bfe774fd15fa0742df801dd3d52e9c395e Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 12 Mar 2013 18:22:16 +0400 Subject: [PATCH 09/11] add autoIndent for LogicQL --- lib/ace/mode/logicql.js | 71 ++++++++++++++++++++++++- lib/ace/mode/logicql_highlight_rules.js | 29 ++++------ 2 files changed, 79 insertions(+), 21 deletions(-) diff --git a/lib/ace/mode/logicql.js b/lib/ace/mode/logicql.js index bc0c16c7..f63f1d0e 100644 --- a/lib/ace/mode/logicql.js +++ b/lib/ace/mode/logicql.js @@ -35,8 +35,9 @@ var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var Tokenizer = require("../tokenizer").Tokenizer; var LogicQLHighlightRules = require("./logicql_highlight_rules").LogicQLHighlightRules; -// TODO: pick appropriate fold mode -var FoldMode = require("./folding/cstyle").FoldMode; +var FoldMode = require("./folding/coffee").FoldMode; +var TokenIterator = require("ace/token_iterator").TokenIterator; +var Range = require("ace/range").Range; var Mode = function() { var highlighter = new LogicQLHighlightRules(); @@ -48,6 +49,72 @@ oop.inherits(Mode, TextMode); (function() { this.lineCommentStart = "//"; this.blockComment = {start: "/*", end: "*/"}; + + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + var match = line.match(); + if (/(-->|<--|<-|->)\s*$/.test(line)) + indent += tab; + return indent; + }; + + this.checkOutdent = function(state, line, input) { + if (input !== "\n" && input !== "\r\n") + return false; + + if (!/^\s+/.test(line)) + return false; + + return true; + }; + + this.autoOutdent = function(state, doc, row) { + var prevLine = doc.getLine(row); + var match = prevLine.match(/^\s+/); + var column = prevLine.lastIndexOf("."); + if (!match || row == 0 || column == -1) return 0; + + var line = doc.getLine(row + 1); + var startRange = this.getMatching(doc, {row: row, column: column}); + if (!startRange || startRange.start.row == row) return 0; + + column = match[0].length; + var indent = this.$getIndent(doc.getLine(startRange.start.row)); + doc.replace(new Range(row + 1, 0, row + 1, column), indent); + }; + + this.getMatching = function(session, row, column) { + if (row == undefined) + row = session.selection.lead + if (typeof row == "object") { + row = row.row; + column = row.column; + } + + var startToken = session.getTokenAt(row, column); + var KW_START = "keyword.start", KW_END = "keyword.end"; + var tok; + + if (startToken.type == KW_START) { + var it = new TokenIterator(session, row, column); + it.step = it.stepForward; + } else if (startToken.type == KW_END) { + var it = new TokenIterator(session, row, column); + it.step = it.stepBackward; + } else + return; + + while (tok = it.step()) { + if (tok.type == KW_START || tok.type == KW_END) + break; + } + if (!tok) + return; + + var col = it.getCurrentTokenColumn(); + var row = it.getCurrentTokenRow(); + return new Range(row, col, row, col + tok.value.length); + }; // Extra logic goes here. }).call(Mode.prototype); diff --git a/lib/ace/mode/logicql_highlight_rules.js b/lib/ace/mode/logicql_highlight_rules.js index 601c5bb2..eb59eda4 100644 --- a/lib/ace/mode/logicql_highlight_rules.js +++ b/lib/ace/mode/logicql_highlight_rules.js @@ -72,26 +72,17 @@ var LogicQLHighlightRules = function() { regex: '`[a-zA-Z_:]+(\\d|\\a)*\\b', //LogicBlox Symbol }, - { token: 'keyword.other', regex: '->', comment: 'Constraint' }, - { token: 'keyword.other', - regex: '-->', - //Level 1 Constraint - }, - { token: 'keyword.other', regex: '<-', comment: 'Rule' }, - { token: 'keyword.other', regex: '<--', comment: 'Level 1 Rule' }, - { token: 'keyword.other', regex: '\\.', comment: 'Terminator' }, - { token: 'keyword.other', regex: '!', comment: 'Negation' }, - { token: 'keyword.other', regex: ',', comment: 'Conjunction' }, - { token: 'keyword.other', regex: ';', comment: 'Disjunction' }, - { token: 'keyword.operator', - regex: '<=|>=|!=|<|>', - //Equality - }, + { token: 'keyword.start', regex: '->', comment: 'Constraint' }, + { token: 'keyword.start', regex: '-->', comment: 'Level 1 Constraint'}, + { token: 'keyword.start', regex: '<-', comment: 'Rule' }, + { token: 'keyword.start', regex: '<--', comment: 'Level 1 Rule' }, + { token: 'keyword.end', regex: '\\.', comment: 'Terminator' }, + { token: 'keyword.other', regex: '!', comment: 'Negation' }, + { token: 'keyword.other', regex: ',', comment: 'Conjunction' }, + { token: 'keyword.other', regex: ';', comment: 'Disjunction' }, + { token: 'keyword.operator', regex: '<=|>=|!=|<|>', comment: 'Equality'}, { token: 'keyword.other', regex: '@', comment: 'Equality' }, - { token: 'keyword.operator', - regex: '\\+|-|\\*|/', - //Arithmetic operations - }, + { token: 'keyword.operator', regex: '\\+|-|\\*|/', comment: 'Arithmetic operations'}, { token: 'keyword', regex: '::', comment: 'Colon colon' }, { token: 'support.function', regex: '\\b(agg\\s*<<)', From ce34f235b88954c6f47dbce641c27d3fa1f3d134 Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 12 Mar 2013 19:13:38 +0400 Subject: [PATCH 10/11] add highlighting of matching -> . --- lib/ace/editor.js | 5 ++++- lib/ace/mode/logicql.js | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 72484840..9b9681e0 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -369,8 +369,11 @@ var Editor = function(renderer, session) { var pos = self.session.findMatchingBracket(self.getCursorPosition()); if (pos) { var range = new Range(pos.row, pos.column, pos.row, pos.column+1); - self.session.$bracketHighlight = self.session.addMarker(range, "ace_bracket", "text"); + } else if (self.session.$mode.getMatching) { + var range = self.session.$mode.getMatching(self.session); } + if (range) + self.session.$bracketHighlight = self.session.addMarker(range, "ace_bracket", "text"); }, 50); }; diff --git a/lib/ace/mode/logicql.js b/lib/ace/mode/logicql.js index f63f1d0e..01c54c15 100644 --- a/lib/ace/mode/logicql.js +++ b/lib/ace/mode/logicql.js @@ -87,14 +87,15 @@ oop.inherits(Mode, TextMode); if (row == undefined) row = session.selection.lead if (typeof row == "object") { - row = row.row; column = row.column; + row = row.row; } var startToken = session.getTokenAt(row, column); var KW_START = "keyword.start", KW_END = "keyword.end"; var tok; - + if (!startToken) + return; if (startToken.type == KW_START) { var it = new TokenIterator(session, row, column); it.step = it.stepForward; From 0895601b7f10204804ef7963377a807bfd544006 Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 12 Mar 2013 19:20:18 +0400 Subject: [PATCH 11/11] fix typo --- lib/ace/mode/logicql.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ace/mode/logicql.js b/lib/ace/mode/logicql.js index 01c54c15..a1696381 100644 --- a/lib/ace/mode/logicql.js +++ b/lib/ace/mode/logicql.js @@ -71,8 +71,8 @@ oop.inherits(Mode, TextMode); this.autoOutdent = function(state, doc, row) { var prevLine = doc.getLine(row); var match = prevLine.match(/^\s+/); - var column = prevLine.lastIndexOf("."); - if (!match || row == 0 || column == -1) return 0; + var column = prevLine.lastIndexOf(".") + 1; + if (!match || !row || !column) return 0; var line = doc.getLine(row + 1); var startRange = this.getMatching(doc, {row: row, column: column});