From c43965fdb50e75bc03a271aa0e569ead1f298e1f Mon Sep 17 00:00:00 2001 From: ukyo Date: Mon, 4 Jun 2012 15:49:50 +0900 Subject: [PATCH 1/4] add jsx mode --- lib/ace/mode/jsx.js | 53 ++++++++++++ lib/ace/mode/jsx_highlight_rules.js | 122 ++++++++++++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 lib/ace/mode/jsx.js create mode 100644 lib/ace/mode/jsx_highlight_rules.js diff --git a/lib/ace/mode/jsx.js b/lib/ace/mode/jsx.js new file mode 100644 index 00000000..1031e9dc --- /dev/null +++ b/lib/ace/mode/jsx.js @@ -0,0 +1,53 @@ +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var Tokenizer = require("../tokenizer").Tokenizer; +var JsxHighlightRules = require("./jsx_highlight_rules").JsxHighlightRules; +var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; +var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; +var CStyleFoldMode = require("./folding/cstyle").FoldMode; + +function Mode() { + this.$tokenizer = new Tokenizer(new JsxHighlightRules().getRules()); + this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CstyleBehaviour(); + this.foldingRules = new CStyleFoldMode(); +} +oop.inherits(Mode, TextMode); + +(function() { + + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + + var tokenizedLine = this.$tokenizer.getLineTokens(line, state); + var tokens = tokenizedLine.tokens; + + if (tokens.length && tokens[tokens.length-1].type == "comment") { + return indent; + } + + if (state == "start") { + var match = line.match(/^.*[\{\(\[]\s*$/); + if (match) { + indent += tab; + } + } + + return indent; + }; + + this.checkOutdent = function(state, line, input) { + return this.$outdent.checkOutdent(line, input); + }; + + this.autoOutdent = function(state, doc, row) { + this.$outdent.autoOutdent(doc, row); + }; + +}).call(Mode.prototype); + +exports.Mode = Mode; +}); diff --git a/lib/ace/mode/jsx_highlight_rules.js b/lib/ace/mode/jsx_highlight_rules.js new file mode 100644 index 00000000..07e6aaa3 --- /dev/null +++ b/lib/ace/mode/jsx_highlight_rules.js @@ -0,0 +1,122 @@ +define(function(require, exports, module) { + var oop = require("../lib/oop"); + var lang = require("../lib/lang"); + var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules; + var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + + var JsxHighlightRules = function() { + var keywords = lang.arrayToMap( + ("break|do|instanceof|typeof|case|else|new|var|catch|finally|return|void|continue|for|switch|while|function|this|" + + "if|throw|" + + "delete|in|try|" + + "class|extends|super|import|implements|interface|static|" + + "number|int|string|boolean|" + + "log|assert").split("|") + ); + + var buildinConstants = lang.arrayToMap( + ("null|true|false|NaN|Infinity|__FILE__|__LINE__|undefined").split("|") + ); + + var reserved = lang.arrayToMap( + ("debugger|with|" + + "const|export|" + + "let|private|public|yield|protected|" + + "extern|native|as|operator").split("|") + ); + + var identifierRe = "[a-zA-Z_][a-zA-Z0-9_]*\\b"; + + this.$rules = { + "start" : [ + { + token : "comment", + regex : "\\/\\/.*$" + }, + DocCommentHighlightRules.getStartRule("doc-start"), + { + token : "comment", // multi line comment + regex : "\\/\\*", + merge : true, + next : "comment" + }, { + token : "string.regexp", + regex : "[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)" + }, { + token : "string", // single line + regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' + }, { + token : "string", // single line + regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" + }, { + token : "constant.numeric", // hex + regex : "0[xX][0-9a-fA-F]+\\b" + }, { + token : "constant.numeric", // float + regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" + }, { + token : "constant.language.boolean", + regex : "(?:true|false)\\b" + }, { + token : [ + "storage.type", + "text", + "entity.name.function" + ], + regex : "(function)(\\s*)(" + identifierRe + ")" + }, { + token : function(value) { + if (value == "this") + return "variable.language"; + else if (value == "function") + return "storage.type"; + else if (keywords.hasOwnProperty(value)) + return "keyword"; + else if (buildinConstants.hasOwnProperty(value)) + return "constant.language"; + else if (/^_?[A-Z][a-zA-Z0-9_]*$/.test(value)) + return "language.support.class"; + else + return "identifier"; + }, + // TODO: Unicode escape sequences + // TODO: Unicode identifiers + regex : identifierRe + }, { + token : "keyword.operator", + regex : "!|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" + }, { + token : "punctuation.operator", + regex : "\\?|\\:|\\,|\\;|\\." + }, { + token : "paren.lparen", + regex : "[[({<]" + }, { + token : "paren.rparen", + regex : "[\\])}>]" + }, { + token : "text", + regex : "\\s+" + } + ], + "comment" : [ + { + token : "comment", // closing comment + regex : ".*?\\*\\/", + next : "start" + }, { + token : "comment", // comment spanning whole line + merge : true, + regex : ".+" + } + ] + }; + + this.embedRules(DocCommentHighlightRules, "doc-", + [ DocCommentHighlightRules.getEndRule("start") ]); + }; + + oop.inherits(JsxHighlightRules, TextHighlightRules); + + exports.JsxHighlightRules = JsxHighlightRules; +}); \ No newline at end of file From de70cfd060893794d4ef0fde536003fdd7a8b872 Mon Sep 17 00:00:00 2001 From: ukyo Date: Mon, 4 Jun 2012 15:51:22 +0900 Subject: [PATCH 2/4] add jsx mode --- demo/kitchen-sink/demo.js | 4 +++- demo/kitchen-sink/docs/jsx.jsx | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 demo/kitchen-sink/docs/jsx.jsx diff --git a/demo/kitchen-sink/demo.js b/demo/kitchen-sink/demo.js index 405a89bb..e73c796b 100644 --- a/demo/kitchen-sink/demo.js +++ b/demo/kitchen-sink/demo.js @@ -104,6 +104,7 @@ var modesByName = { java: ["Java" , "java"], javascript: ["JavaScript" , "js"], json: ["JSON" , "json"], + jsx: ["JSX" , "jsx"], latex: ["LaTeX" , "latex|tex|ltx|bib"], less: ["LESS" , "less"], liquid: ["Liquid" , "liquid"], @@ -201,7 +202,8 @@ var docs = { "docs/latex.tex": {name: "LaTeX", wrapped: true}, "docs/sql.sql": {name: "SQL", wrapped: true}, "docs/pgsql.pgsql": {name: "pgSQL", wrapped: true}, - "docs/golang.go": "Go" + "docs/golang.go": "Go", + "docs/jsx.jsx": "JSX" } var ownSource = { diff --git a/demo/kitchen-sink/docs/jsx.jsx b/demo/kitchen-sink/docs/jsx.jsx new file mode 100644 index 00000000..fbbeb662 --- /dev/null +++ b/demo/kitchen-sink/docs/jsx.jsx @@ -0,0 +1,9 @@ +/*EXPECTED +hello world! +*/ +class Test { + static function run() : void { + // console.log("hello world!"); + log "hello world!"; + } +} \ No newline at end of file From 5c7fb274d781aa2017ca0e15249a3996af1ab030 Mon Sep 17 00:00:00 2001 From: ukyo Date: Mon, 4 Jun 2012 17:46:11 +0900 Subject: [PATCH 3/4] fix missing keywords --- lib/ace/mode/jsx_highlight_rules.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/ace/mode/jsx_highlight_rules.js b/lib/ace/mode/jsx_highlight_rules.js index 07e6aaa3..dc7c8253 100644 --- a/lib/ace/mode/jsx_highlight_rules.js +++ b/lib/ace/mode/jsx_highlight_rules.js @@ -6,11 +6,11 @@ define(function(require, exports, module) { var JsxHighlightRules = function() { var keywords = lang.arrayToMap( - ("break|do|instanceof|typeof|case|else|new|var|catch|finally|return|void|continue|for|switch|while|function|this|" + + ("break|do|instanceof|typeof|case|else|new|var|catch|finally|return|void|continue|for|switch|default|while|function|this|" + "if|throw|" + "delete|in|try|" + - "class|extends|super|import|implements|interface|static|" + - "number|int|string|boolean|" + + "class|extends|super|import|from|into|implements|interface|static|mixin|override|abstract|final|" + + "number|int|string|boolean|variant|" + "log|assert").split("|") ); @@ -22,7 +22,7 @@ define(function(require, exports, module) { ("debugger|with|" + "const|export|" + "let|private|public|yield|protected|" + - "extern|native|as|operator").split("|") + "extern|native|as|operator|__fake__|__readonly__").split("|") ); var identifierRe = "[a-zA-Z_][a-zA-Z0-9_]*\\b"; @@ -70,7 +70,7 @@ define(function(require, exports, module) { return "variable.language"; else if (value == "function") return "storage.type"; - else if (keywords.hasOwnProperty(value)) + else if (keywords.hasOwnProperty(value) || reserved.hasOwnProperty(value)) return "keyword"; else if (buildinConstants.hasOwnProperty(value)) return "constant.language"; From 91df64cbdab28ae3bb407f6b63c337e84479214d Mon Sep 17 00:00:00 2001 From: ukyo Date: Sat, 9 Jun 2012 00:07:06 +0900 Subject: [PATCH 4/4] fix regex --- lib/ace/mode/jsx_highlight_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ace/mode/jsx_highlight_rules.js b/lib/ace/mode/jsx_highlight_rules.js index dc7c8253..0700b011 100644 --- a/lib/ace/mode/jsx_highlight_rules.js +++ b/lib/ace/mode/jsx_highlight_rules.js @@ -63,7 +63,7 @@ define(function(require, exports, module) { "text", "entity.name.function" ], - regex : "(function)(\\s*)(" + identifierRe + ")" + regex : "(function)(\\s+)(" + identifierRe + ")" }, { token : function(value) { if (value == "this")