From a81b0a6f49503f402fdc1fd3b9f235f5d6b56f2a Mon Sep 17 00:00:00 2001 From: btilford Date: Fri, 24 Jun 2011 21:24:32 -0600 Subject: [PATCH 1/2] Groovy / Scala highlighting --- demo/demo.js | 31 ++++- index.html | 47 +++++++ lib/ace/mode/groovy.js | 26 ++++ lib/ace/mode/groovy_highlight_rules.js | 164 ++++++++++++++++++++++++ lib/ace/mode/scala.js | 26 ++++ lib/ace/mode/scala_highlight_rules.js | 165 +++++++++++++++++++++++++ 6 files changed, 457 insertions(+), 2 deletions(-) create mode 100644 lib/ace/mode/groovy.js create mode 100644 lib/ace/mode/groovy_highlight_rules.js create mode 100644 lib/ace/mode/scala.js create mode 100644 lib/ace/mode/scala_highlight_rules.js diff --git a/demo/demo.js b/demo/demo.js index 22e1cc59..0b06a779 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -68,6 +68,9 @@ exports.launch = function(env) { var SvgMode = require("ace/mode/svg").Mode; var TextileMode = require("ace/mode/textile").Mode; var TextMode = require("ace/mode/text").Mode; + var GroovyMode = require("ace/mode/groovy").Mode; + var ScalaMode = require("ace/mode/scala").Mode; + var UndoManager = require("ace/undomanager").UndoManager; var vim = require("ace/keyboard/keybinding/vim").Vim; @@ -167,6 +170,17 @@ exports.launch = function(env) { docs.textile.setMode(new TextileMode()); docs.textile.setUndoManager(new UndoManager()); + docs.textile = new EditSession(document.getElementById("groovy").innerHTML); + docs.textile.setMode(new GroovyMode()); + docs.textile.setUndoManager(new UndoManager()); + + docs.textile = new EditSession(document.getElementById("scala").innerHTML); + docs.textile.setMode(new ScalaMode()); + docs.textile.setUndoManager(new UndoManager()); + + + + // Add a "name" property to all docs for (doc in docs) { docs[doc].name = doc; @@ -206,7 +220,9 @@ exports.launch = function(env) { perl: new PerlMode(), clojure: new ClojureMode(), ocaml: new OcamlMode(), - csharp: new CSharpMode() + csharp: new CSharpMode(), + groovy: new GroovyMode(), + scala: new ScalaMode() }; function getMode() { @@ -297,6 +313,12 @@ exports.launch = function(env) { else if (mode instanceof TextileMode) { modeEl.value = "textile"; } + else if (mode instanceof GroovyMode) { + modeEl.value = "groovy"; + } + else if (mode instanceof ScalaMode) { + modeEl.value = "scala"; + } else { modeEl.value = "text"; } @@ -455,8 +477,9 @@ exports.launch = function(env) { }); event.addListener(container, "drop", function(e) { + var file try { - var file = e.dataTransfer.files[0]; + file = e.dataTransfer.files[0]; } catch(e) { return event.stopEvent(); } @@ -497,6 +520,10 @@ exports.launch = function(env) { mode = "perl"; } else if (/^.*\.(ml|mli)$/i.test(file.name)) { mode = "ocaml"; + } else if (/^.*\.(groovy)$/i.test(file.name)) { + mode = "groovy"; + } else if (/^.*\.(scala)$/i.test(file.name)) { + mode = "scala"; } env.editor.onTextInput(reader.result); diff --git a/index.html b/index.html index 72b0609f..01af8091 100644 --- a/index.html +++ b/index.html @@ -35,6 +35,8 @@ + + @@ -62,6 +64,8 @@ + + @@ -631,6 +635,49 @@ bg. Blockquote! + + + diff --git a/lib/ace/mode/groovy.js b/lib/ace/mode/groovy.js new file mode 100644 index 00000000..12930aa5 --- /dev/null +++ b/lib/ace/mode/groovy.js @@ -0,0 +1,26 @@ +define(function(require, exports, module) { + +var oop = require("pilot/oop"); +var JavaScriptMode = require("ace/mode/javascript").Mode; +var Tokenizer = require("ace/tokenizer").Tokenizer; +var GroovyHighlightRules = require("ace/mode/groovy_highlight_rules").JavaHighlightRules; +var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent; +var CstyleBehaviour = require("ace/mode/behaviour/cstyle").CstyleBehaviour; + +var Mode = function() { + this.$tokenizer = new Tokenizer(new GroovyHighlightRules().getRules()); + this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CstyleBehaviour(); +}; +oop.inherits(Mode, JavaScriptMode); + +(function() { + + this.createWorker = function(session) { + return null; + }; + +}).call(Mode.prototype); + +exports.Mode = Mode; +}); diff --git a/lib/ace/mode/groovy_highlight_rules.js b/lib/ace/mode/groovy_highlight_rules.js new file mode 100644 index 00000000..c71161ff --- /dev/null +++ b/lib/ace/mode/groovy_highlight_rules.js @@ -0,0 +1,164 @@ +define(function(require, exports, module) { + +var oop = require("pilot/oop"); +var lang = require("pilot/lang"); +var DocCommentHighlightRules = require("ace/mode/doc_comment_highlight_rules").DocCommentHighlightRules; +var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules; + +var GroovyHighlightRules = function() { + + var keywords = lang.arrayToMap( + ("assert|with|abstract|continue|for|new|switch|" + + "assert|default|goto|package|synchronized|" + + "boolean|do|if|private|this|" + + "break|double|implements|protected|throw|" + + "byte|else|import|public|throws|" + + "case|enum|instanceof|return|transient|" + + "catch|extends|int|short|try|" + + "char|final|interface|static|void|" + + "class|finally|long|strictfp|volatile|" + + "def|float|native|super|while").split("|") + ); + + var buildinConstants = lang.arrayToMap( + ("null|Infinity|NaN|undefined").split("|") + ); + + var langClasses = lang.arrayToMap( + ("AbstractMethodError|AssertionError|ClassCircularityError|"+ + "ClassFormatError|Deprecated|EnumConstantNotPresentException|"+ + "ExceptionInInitializerError|IllegalAccessError|"+ + "IllegalThreadStateException|InstantiationError|InternalError|"+ + "NegativeArraySizeException|NoSuchFieldError|Override|Process|"+ + "ProcessBuilder|SecurityManager|StringIndexOutOfBoundsException|"+ + "SuppressWarnings|TypeNotPresentException|UnknownError|"+ + "UnsatisfiedLinkError|UnsupportedClassVersionError|VerifyError|"+ + "InstantiationException|IndexOutOfBoundsException|"+ + "ArrayIndexOutOfBoundsException|CloneNotSupportedException|"+ + "NoSuchFieldException|IllegalArgumentException|NumberFormatException|"+ + "SecurityException|Void|InheritableThreadLocal|IllegalStateException|"+ + "InterruptedException|NoSuchMethodException|IllegalAccessException|"+ + "UnsupportedOperationException|Enum|StrictMath|Package|Compiler|"+ + "Readable|Runtime|StringBuilder|Math|IncompatibleClassChangeError|"+ + "NoSuchMethodError|ThreadLocal|RuntimePermission|ArithmeticException|"+ + "NullPointerException|Long|Integer|Short|Byte|Double|Number|Float|"+ + "Character|Boolean|StackTraceElement|Appendable|StringBuffer|"+ + "Iterable|ThreadGroup|Runnable|Thread|IllegalMonitorStateException|"+ + "StackOverflowError|OutOfMemoryError|VirtualMachineError|"+ + "ArrayStoreException|ClassCastException|LinkageError|"+ + "NoClassDefFoundError|ClassNotFoundException|RuntimeException|"+ + "Exception|ThreadDeath|Error|Throwable|System|ClassLoader|"+ + "Cloneable|Class|CharSequence|Comparable|String|Object").split("|") + ); + + var importClasses = lang.arrayToMap( + ("").split("|") + ); + // regexp must not have capturing parentheses. Use (?:) instead. + // regexps are ordered -> the first match is used + + this.$rules = { + "start" : [ + { + token : "comment", + regex : "\\/\\/.*$" + }, + new DocCommentHighlightRules().getStartRule("doc-start"), + { + token : "comment", // multi line comment + regex : "\\/\\*", + next : "comment" + }, { + token : "comment", // multi line comment + regex : "\\/\\*\\*", + 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 : function(value) { + if (value == "this") + return "variable.language"; + else if (keywords.hasOwnProperty(value)) + return "keyword"; + else if (langClasses.hasOwnProperty(value)) + return "support.function"; + else if (importClasses.hasOwnProperty(value)) + return "support.function"; + else if (buildinConstants.hasOwnProperty(value)) + return "constant.language"; + else + return "identifier"; + }, + // TODO: Unicode escape sequences + // TODO: Unicode identifiers + regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + }, { + token : "keyword.operator", + regex : "\\?:|\\?\\.|\\*\\.|<=>|=~|==~|\\.@|\\*\\.@|\\.&|as|in|is|!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" + }, { + token : "lparen", + regex : "[[({]" + }, { + token : "rparen", + regex : "[\\])}]" + }, { + token : "text", + regex : "\\s+" + } + ], + "comment" : [ + { + token : "comment", // closing comment + regex : ".*?\\*\\/", + next : "start" + }, { + token : "comment", // comment spanning whole line + regex : ".+" + } + ], + "qqstring" : [ + { + token : "string", + regex : '(?:(?:\\\\.)|(?:[^"\\\\]))*?"', + next : "start" + }, { + token : "string", + regex : '.+' + } + ], + "qstring" : [ + { + token : "string", + regex : "(?:(?:\\\\.)|(?:[^'\\\\]))*?'", + next : "start" + }, { + token : "string", + regex : '.+' + } + ] + }; + + this.embedRules(DocCommentHighlightRules, "doc-", + [ new DocCommentHighlightRules().getEndRule("start") ]); +}; + +oop.inherits(GroovyHighlightRules, TextHighlightRules); + +exports.GroovyHighlightRules = GroovyHighlightRules; +}); diff --git a/lib/ace/mode/scala.js b/lib/ace/mode/scala.js new file mode 100644 index 00000000..5342eca3 --- /dev/null +++ b/lib/ace/mode/scala.js @@ -0,0 +1,26 @@ +define(function(require, exports, module) { + +var oop = require("pilot/oop"); +var JavaScriptMode = require("ace/mode/javascript").Mode; +var Tokenizer = require("ace/tokenizer").Tokenizer; +var JavaHighlightRules = require("ace/mode/scala_highlight_rules").ScalaHighlightRules; +var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent; +var CstyleBehaviour = require("ace/mode/behaviour/cstyle").CstyleBehaviour; + +var Mode = function() { + this.$tokenizer = new Tokenizer(new ScalaHighlightRules().getRules()); + this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CstyleBehaviour(); +}; +oop.inherits(Mode, JavaScriptMode); + +(function() { + + this.createWorker = function(session) { + return null; + }; + +}).call(Mode.prototype); + +exports.Mode = Mode; +}); diff --git a/lib/ace/mode/scala_highlight_rules.js b/lib/ace/mode/scala_highlight_rules.js new file mode 100644 index 00000000..641a6a9a --- /dev/null +++ b/lib/ace/mode/scala_highlight_rules.js @@ -0,0 +1,165 @@ +define(function(require, exports, module) { + +var oop = require("pilot/oop"); +var lang = require("pilot/lang"); +var DocCommentHighlightRules = require("ace/mode/doc_comment_highlight_rules").DocCommentHighlightRules; +var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules; + +var ScalaHighlightRules = function() { + + // taken from http://download.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html + var keywords = lang.arrayToMap( + ( + "case|default|do|else|for|if|match|while|throw|return|try|catch|finally|yield|" + + "abstract|class|def|extends|final|forSome|implicit|import|lazy|new|object|" + + "override|package|private|protected|sealed|super|this|trait|type|val|var|with" + ).split("|") + ); + + var buildinConstants = lang.arrayToMap( + ("true|false").split("|") + ); + + var langClasses = lang.arrayToMap( + ("AbstractMethodError|AssertionError|ClassCircularityError|"+ + "ClassFormatError|Deprecated|EnumConstantNotPresentException|"+ + "ExceptionInInitializerError|IllegalAccessError|"+ + "IllegalThreadStateException|InstantiationError|InternalError|"+ + + "NegativeArraySizeException|NoSuchFieldError|Override|Process|"+ + "ProcessBuilder|SecurityManager|StringIndexOutOfBoundsException|"+ + "SuppressWarnings|TypeNotPresentException|UnknownError|"+ + "UnsatisfiedLinkError|UnsupportedClassVersionError|VerifyError|"+ + "InstantiationException|IndexOutOfBoundsException|"+ + "ArrayIndexOutOfBoundsException|CloneNotSupportedException|"+ + "NoSuchFieldException|IllegalArgumentException|NumberFormatException|"+ + "SecurityException|Void|InheritableThreadLocal|IllegalStateException|"+ + "InterruptedException|NoSuchMethodException|IllegalAccessException|"+ + "UnsupportedOperationException|Enum|StrictMath|Package|Compiler|"+ + "Readable|Runtime|StringBuilder|Math|IncompatibleClassChangeError|"+ + "NoSuchMethodError|ThreadLocal|RuntimePermission|ArithmeticException|"+ + "NullPointerException|Long|Integer|Short|Byte|Double|Number|Float|"+ + "Character|Boolean|StackTraceElement|Appendable|StringBuffer|"+ + "Iterable|ThreadGroup|Runnable|Thread|IllegalMonitorStateException|"+ + "StackOverflowError|OutOfMemoryError|VirtualMachineError|"+ + "ArrayStoreException|ClassCastException|LinkageError|"+ + "NoClassDefFoundError|ClassNotFoundException|RuntimeException|"+ + "Exception|ThreadDeath|Error|Throwable|System|ClassLoader|"+ + "Cloneable|Class|CharSequence|Comparable|String|Object|" + + "Unit|Any|AnyVal|AnyRef|Null|ScalaObject|Singleton|Seq|Iterable|List|" + + "Option|Array|Char|Byte|Short|Int|Long|Nothing" + + ).split("|") + ); + + var importClasses = lang.arrayToMap( + ("").split("|") + ); + // regexp must not have capturing parentheses. Use (?:) instead. + // regexps are ordered -> the first match is used + + this.$rules = { + "start" : [ + { + token : "comment", + regex : "\\/\\/.*$" + }, + new DocCommentHighlightRules().getStartRule("doc-start"), + { + token : "comment", // multi line comment + regex : "\\/\\*", + next : "comment" + }, { + token : "comment", // multi line comment + regex : "\\/\\*\\*", + 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 : function(value) { + if (value == "this") + return "variable.language"; + else if (keywords.hasOwnProperty(value)) + return "keyword"; + else if (langClasses.hasOwnProperty(value)) + return "support.function"; + else if (importClasses.hasOwnProperty(value)) + return "support.function"; + else if (buildinConstants.hasOwnProperty(value)) + return "constant.language"; + else + return "identifier"; + }, + // TODO: Unicode escape sequences + // TODO: Unicode identifiers + regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + }, { + token : "keyword.operator", + regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" + }, { + token : "lparen", + regex : "[[({]" + }, { + token : "rparen", + regex : "[\\])}]" + }, { + token : "text", + regex : "\\s+" + } + ], + "comment" : [ + { + token : "comment", // closing comment + regex : ".*?\\*\\/", + next : "start" + }, { + token : "comment", // comment spanning whole line + regex : ".+" + } + ], + "qqstring" : [ + { + token : "string", + regex : '(?:(?:\\\\.)|(?:[^"\\\\]))*?"', + next : "start" + }, { + token : "string", + regex : '.+' + } + ], + "qstring" : [ + { + token : "string", + regex : "(?:(?:\\\\.)|(?:[^'\\\\]))*?'", + next : "start" + }, { + token : "string", + regex : '.+' + } + ] + }; + + this.embedRules(DocCommentHighlightRules, "doc-", + [ new DocCommentHighlightRules().getEndRule("start") ]); +}; + +oop.inherits(ScalaHighlightRules, TextHighlightRules); + +exports.ScalaHighlightRules = ScalaHighlightRules; +}); From 47b8fdef17a603e3a7097133db7deb690817b2eb Mon Sep 17 00:00:00 2001 From: btilford Date: Fri, 24 Jun 2011 21:34:57 -0600 Subject: [PATCH 2/2] Fixed demo config issues for groovy/scala highlighting --- demo/demo.js | 12 ++++++------ lib/ace/mode/groovy.js | 2 +- lib/ace/mode/scala.js | 2 +- lib/ace/mode/scala_highlight_rules.js | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/demo/demo.js b/demo/demo.js index 0b06a779..e338bb10 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -170,13 +170,13 @@ exports.launch = function(env) { docs.textile.setMode(new TextileMode()); docs.textile.setUndoManager(new UndoManager()); - docs.textile = new EditSession(document.getElementById("groovy").innerHTML); - docs.textile.setMode(new GroovyMode()); - docs.textile.setUndoManager(new UndoManager()); + docs.groovy = new EditSession(document.getElementById("groovy").innerHTML); + docs.groovy.setMode(new GroovyMode()); + docs.groovy.setUndoManager(new UndoManager()); - docs.textile = new EditSession(document.getElementById("scala").innerHTML); - docs.textile.setMode(new ScalaMode()); - docs.textile.setUndoManager(new UndoManager()); + docs.scala = new EditSession(document.getElementById("scala").innerHTML); + docs.scala.setMode(new ScalaMode()); + docs.scala.setUndoManager(new UndoManager()); diff --git a/lib/ace/mode/groovy.js b/lib/ace/mode/groovy.js index 12930aa5..b0d51d87 100644 --- a/lib/ace/mode/groovy.js +++ b/lib/ace/mode/groovy.js @@ -3,7 +3,7 @@ define(function(require, exports, module) { var oop = require("pilot/oop"); var JavaScriptMode = require("ace/mode/javascript").Mode; var Tokenizer = require("ace/tokenizer").Tokenizer; -var GroovyHighlightRules = require("ace/mode/groovy_highlight_rules").JavaHighlightRules; +var GroovyHighlightRules = require("ace/mode/groovy_highlight_rules").GroovyHighlightRules; var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent; var CstyleBehaviour = require("ace/mode/behaviour/cstyle").CstyleBehaviour; diff --git a/lib/ace/mode/scala.js b/lib/ace/mode/scala.js index 5342eca3..f1690fb6 100644 --- a/lib/ace/mode/scala.js +++ b/lib/ace/mode/scala.js @@ -3,7 +3,7 @@ define(function(require, exports, module) { var oop = require("pilot/oop"); var JavaScriptMode = require("ace/mode/javascript").Mode; var Tokenizer = require("ace/tokenizer").Tokenizer; -var JavaHighlightRules = require("ace/mode/scala_highlight_rules").ScalaHighlightRules; +var ScalaHighlightRules = require("ace/mode/scala_highlight_rules").ScalaHighlightRules; var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent; var CstyleBehaviour = require("ace/mode/behaviour/cstyle").CstyleBehaviour; diff --git a/lib/ace/mode/scala_highlight_rules.js b/lib/ace/mode/scala_highlight_rules.js index 641a6a9a..d3987929 100644 --- a/lib/ace/mode/scala_highlight_rules.js +++ b/lib/ace/mode/scala_highlight_rules.js @@ -11,7 +11,7 @@ var ScalaHighlightRules = function() { var keywords = lang.arrayToMap( ( "case|default|do|else|for|if|match|while|throw|return|try|catch|finally|yield|" + - "abstract|class|def|extends|final|forSome|implicit|import|lazy|new|object|" + + "abstract|class|def|extends|final|forSome|implicit|implicits|import|lazy|new|object|" + "override|package|private|protected|sealed|super|this|trait|type|val|var|with" ).split("|") );