diff --git a/demo/demo.js b/demo/demo.js index 6ad4a8d1..542b6087 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -46,6 +46,7 @@ exports.launch = function(env) { var Renderer = require("ace/virtual_renderer").VirtualRenderer; var theme = require("ace/theme/textmate"); var EditSession = require("ace/edit_session").EditSession; + var JavaScriptMode = require("ace/mode/javascript").Mode; var CssMode = require("ace/mode/css").Mode; var HtmlMode = require("ace/mode/html").Mode; @@ -55,6 +56,7 @@ exports.launch = function(env) { var JavaMode = require("ace/mode/java").Mode; var RubyMode = require("ace/mode/ruby").Mode; var CCPPMode = require("ace/mode/c_cpp").Mode; + var CoffeeMode = require("ace/mode/coffee").Mode; var TextMode = require("ace/mode/text").Mode; var UndoManager = require("ace/undomanager").UndoManager; @@ -117,6 +119,10 @@ exports.launch = function(env) { docs.c_cpp.setMode(new CCPPMode()); docs.c_cpp.setUndoManager(new UndoManager()); + docs.coffee = new EditSession(document.getElementById("coffeetext").innerHTML); + docs.coffee.setMode(new CoffeeMode()); + docs.coffee.setUndoManager(new UndoManager()); + var container = document.getElementById("editor"); env.editor = new Editor(new Renderer(container, theme)); @@ -130,7 +136,8 @@ exports.launch = function(env) { php: new PhpMode(), java: new JavaMode(), ruby: new RubyMode(), - c_cpp: new CCPPMode() + c_cpp: new CCPPMode(), + coffee: new CoffeeMode() }; function getMode() { @@ -172,6 +179,9 @@ exports.launch = function(env) { else if (mode instanceof CCPPMode) { modeEl.value = "c_cpp"; } + else if (mode instanceof CoffeeMode) { + modeEl.value = "coffee"; + } else { modeEl.value = "text"; } @@ -303,6 +313,8 @@ exports.launch = function(env) { mode = "ruby"; } else if (/^.*\.(c|cpp|h|hpp|cxx)$/i.test(file.name)) { mode = "c_cpp"; + } else if (/^.*\.coffee$/i.test(file.name)) { + mode = "coffee"; } env.editor.onTextInput(reader.result); diff --git a/editor.html b/editor.html index 6e29467c..82816e05 100644 --- a/editor.html +++ b/editor.html @@ -22,6 +22,7 @@ + @@ -77,7 +78,8 @@ - + + @@ -238,6 +240,30 @@ int main () cout << a; return 0; } + + + diff --git a/lib/ace/mode/coffee.js b/lib/ace/mode/coffee.js new file mode 100644 index 00000000..32c692b4 --- /dev/null +++ b/lib/ace/mode/coffee.js @@ -0,0 +1,88 @@ +/* ***** 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): + * Satoshi Murakami + * + * 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 Tokenizer = require("ace/tokenizer").Tokenizer + , Rules = require("ace/mode/coffee_highlight_rules").CoffeeHighlightRules + , Outdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent + , Range = require("ace/range").Range +; +require("pilot/oop").inherits(CoffeeMode, require("ace/mode/text").Mode); + +function CoffeeMode() { + this.$tokenizer = new Tokenizer(new Rules().getRules()); + this.$outdent = new Outdent(); +} +var proto = CoffeeMode.prototype + , indenter = /(?:[({[=:]|[-=]>|\b(?:else|switch|try|catch(?:\s*[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)?|finally))\s*$/ + , commentLine = /^(\s*)#/ + , hereComment = /^\s*###(?!#)/ + , indentation = /^\s*/ +; +proto.getNextLineIndent = function(state, line, tab){ + var indent = this.$getIndent(line) + , tokens = this.$tokenizer.getLineTokens(line, state).tokens + ; + if (!(tokens.length && tokens[tokens.length - 1].type === 'comment') && + state === 'start' && indenter.test(line)) + indent += tab; + return indent; +}; +proto.toggleCommentLines = function(state, doc, startRow, endRow){ + var out, range = new Range(0, 0, 0, 0); + for (var i = startRow; i <= endRow; ++i) { + var line = doc.getLine(i); + if (hereComment.test(line)) continue; + line = (out = commentLine.test(line)) + ? line.replace(commentLine, '$1') + : line.replace(indentation, '$&#'); + range.end.row = range.start.row = i; + range.end.column = line.length + 1; + doc.replace(range, line); + } + return 1 - out * 2; +}; +proto.checkOutdent = function(state, line, input) { + return this.$outdent.checkOutdent(line, input); +}; +proto.autoOutdent = function(state, doc, row) { + return this.$outdent.autoOutdent(doc, row); +}; + +exports.Mode = CoffeeMode; +}); diff --git a/lib/ace/mode/coffee_highlight_rules.js b/lib/ace/mode/coffee_highlight_rules.js new file mode 100644 index 00000000..c28fd8f9 --- /dev/null +++ b/lib/ace/mode/coffee_highlight_rules.js @@ -0,0 +1,182 @@ +/* ***** 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): + * Satoshi Murakami + * + * 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) { + +require("pilot/oop").inherits( + CoffeeHighlightRules, + require("ace/mode/text_highlight_rules").TextHighlightRules); + +function CoffeeHighlightRules() { +var identifier = "[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*" + , keywordend = "(?![$\\w]|\\s*:)" + , stringfill = {token: "string", regex: ".+"} +; +this.$rules = + { start: + [ { token: "identifier" + , regex: "(?:@|(?:\\.|::)\\s*)" + identifier + } + , { token: "keyword" + , regex: "(?:t(?:h(?:is|row|en)|ry|ypeof)|s(?:uper|witch)|return|b(?:reak|y)|c(?:ontinue|atch|lass)|i(?:n(?:stanceof)?|s(?:nt)?|f)|e(?:lse|xtends)|f(?:or (?:own)?|inally|unction)|wh(?:ile|en)|n(?:ew|ot?)|d(?:e(?:lete|bugger)|o)|loop|o(?:ff?|[rn])|un(?:less|til)|and|yes)" + keywordend + } + , { token: "constant.language" + , regex: "(?:true|false|null|undefined)" + keywordend + } + , { token: "invalid.illegal" + , regex: "(?:c(?:ase|onst)|default|function|v(?:ar|oid)|with|e(?:num|xport)|i(?:mplements|nterface)|let|p(?:ackage|r(?:ivate|otected)|ublic)|static|yield|__(?:hasProp|extends|slice|bind|indexOf))" + keywordend + } + , { token: "language.support.class" + , regex: "(?:Array|Boolean|Date|Function|Number|Object|R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|TypeError|URIError)" + keywordend + } + , { token: "language.support.function" + , regex: "(?:Math|JSON|is(?:NaN|Finite)|parse(?:Int|Float)|encodeURI(?:Component)?|decodeURI(?:Component)?)" + keywordend + } + , { token: "identifier" + , regex: identifier + } + , { token: "constant.numeric" + , regex: "(?:0x[\\da-fA-F]+|(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:[eE][+-]?\\d+)?)" + } + , { token: "string" + , regex: "'''" + , next : "qdoc" + } + , { token: "string" + , regex: '"""' + , next : "qqdoc" + } + , { token: "string" + , regex: "'" + , next : "qstring" + } + , { token: "string" + , regex: '"' + , next : "qqstring" + } + , { token: "string" + , regex: "`" + , next : "js" + } + , { token: "string.regex" + , regex: "///" + , next : "heregex" + } + , { token: "string.regex" + , regex: "/(?!\\s)[^[/\\n\\\\]*(?: (?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[/\\n\\\\]*)*/[imgy]{0,4}(?!\\w)" + } + , { token: "comment" + , regex: "###(?!#)" + , next : "comment" + } + , { token: "comment" + , regex: "#.*" + } + , { token: "lparen" + , regex: "[({[]" + } + , { token: "rparen" + , regex: "[\\]})]" + } + , { token: "keyword.operator" + , regex: "\\S+" + } + , { token: "text" + , regex: "\\s+" + } + ] + , qdoc: + [ { token: "string" + , regex: ".*?'''" + , next : "start" + } + , stringfill + ] + , qqdoc: + [ { token: "string" + , regex: '.*?"""' + , next : "start" + } + , stringfill + ] + , qstring: + [ { token: "string" + , regex: "[^\\\\']*(?:\\\\.[^\\\\']*)*'" + , next : "start" + } + , stringfill + ] + , qqstring: + [ { token: "string" + , regex: '[^\\\\"]*(?:\\\\.[^\\\\"]*)*"' + , next : "start" + } + , stringfill + ] + , js: + [ { token: "string" + , regex: "[^\\\\`]*(?:\\\\.[^\\\\`]*)*`" + , next : "start" + } + , stringfill + ] + , heregex: + [ { token: "string.regex" + , regex: '.*?///[imgy]{0,4}' + , next : "start" + } + , { token: "comment.regex" + , regex: "\\s+(?:#.*)?" + } + , { token: "string.regex" + , regex: "\\S+" + } + ] + , comment: + [ { token: "comment" + , regex: '.*?###' + , next : "start" + } + , { token: "comment" + , regex: ".+" + } + ] + }; +} + +exports.CoffeeHighlightRules = CoffeeHighlightRules; +});