diff --git a/demo/kitchen-sink/docs/julia.jl b/demo/kitchen-sink/docs/julia.jl index 97178469..f558ae22 100644 --- a/demo/kitchen-sink/docs/julia.jl +++ b/demo/kitchen-sink/docs/julia.jl @@ -2,7 +2,7 @@ for op = (:+, :*, :&, :|, :$) @eval ($op)(a,b,c) = ($op)(($op)(a,b),c) end - +v = α'; function g(x,y) return x * y x + y diff --git a/demo/r.js/build.js b/demo/r.js/build.js new file mode 100644 index 00000000..028d2234 --- /dev/null +++ b/demo/r.js/build.js @@ -0,0 +1,20 @@ +({ + optimize: "none", + preserveLicenseComments: false, + name: "node_modules/almond/almond", + baseUrl: "../../", + paths: { + ace : "lib/ace", + demo: "demo/kitchen-sink" + }, + packages: [ + ], + include: [ + "ace/ace" + ], + exclude: [ + ], + out: "./packed.js", + useStrict: true, + wrap: false +}) \ No newline at end of file diff --git a/demo/r.js/editor.html b/demo/r.js/editor.html new file mode 100644 index 00000000..9f7a47bf --- /dev/null +++ b/demo/r.js/editor.html @@ -0,0 +1,36 @@ + + + +
+
+
+ ++ demo showing Ace usage with r.js: + + install r.js and almond + and run `r.js -o demo/r.js/build.js` + + note that you also need ace/build/src to lazy load modes and themes + require("ace/config").set("basePath", "../../build/src"); + require("ace/config").set("packaged", true); ++ + + + + + diff --git a/lib/ace/ace.js b/lib/ace/ace.js index a2261355..d7da2fb7 100644 --- a/lib/ace/ace.js +++ b/lib/ace/ace.js @@ -46,12 +46,12 @@ var Editor = require("./editor").Editor; var EditSession = require("./edit_session").EditSession; var UndoManager = require("./undomanager").UndoManager; var Renderer = require("./virtual_renderer").VirtualRenderer; -var MultiSelect = require("./multi_select").MultiSelect; // The following require()s are for inclusion in the built ace file require("./worker/worker_client"); require("./keyboard/hash_handler"); require("./placeholder"); +require("./multi_select"); require("./mode/folding/fold_mode"); require("./theme/textmate"); require("./ext/error_marker"); @@ -74,7 +74,7 @@ exports.require = require; exports.edit = function(el) { if (typeof(el) == "string") { var _id = el; - var el = document.getElementById(_id); + el = document.getElementById(_id); if (!el) throw new Error("ace.edit can't find div #" + _id); } @@ -86,7 +86,6 @@ exports.edit = function(el) { el.innerHTML = ''; var editor = new Editor(new Renderer(el)); - new MultiSelect(editor); editor.setSession(doc); var env = { diff --git a/lib/ace/keyboard/keybinding.js b/lib/ace/keyboard/keybinding.js index d5edd4f8..c43d7930 100644 --- a/lib/ace/keyboard/keybinding.js +++ b/lib/ace/keyboard/keybinding.js @@ -36,7 +36,7 @@ var event = require("../lib/event"); var KeyBinding = function(editor) { this.$editor = editor; - this.$data = {}; + this.$data = {editor: editor}; this.$handlers = []; this.setDefaultHandler(editor.commands); }; @@ -46,7 +46,6 @@ var KeyBinding = function(editor) { this.removeKeyboardHandler(this.$defaultHandler); this.$defaultHandler = kb; this.addKeyboardHandler(kb, 0); - this.$data = {editor: this.$editor}; }; this.setKeyboardHandler = function(kb) { diff --git a/lib/ace/keyboard/vim.js b/lib/ace/keyboard/vim.js index 8b8bef2c..deea8d2f 100644 --- a/lib/ace/keyboard/vim.js +++ b/lib/ace/keyboard/vim.js @@ -120,23 +120,24 @@ exports.handler = { return null; var editor = data.editor; + var vimState = data.vimState || "start"; if (hashId == 1) key = "ctrl-" + key; if (key == "ctrl-c") { if (!useragent.isMac && editor.getCopyText()) { editor.once("copy", function() { - if (data.state == "start") + if (vimState == "start") coreCommands.stop.exec(editor); else editor.selection.clearSelection(); }); return {command: "null", passEvent: true}; } - return {command: coreCommands.stop}; + return {command: coreCommands.stop}; } else if ((key == "esc" && hashId === 0) || key == "ctrl-[") { return {command: coreCommands.stop}; - } else if (data.state == "start") { + } else if (vimState == "start") { if (useragent.isMac && this.handleMacRepeat(data, hashId, key)) { hashId = -1; key = data.inputChar; diff --git a/lib/ace/keyboard/vim/maps/util.js b/lib/ace/keyboard/vim/maps/util.js index a216c2cc..1eadde84 100644 --- a/lib/ace/keyboard/vim/maps/util.js +++ b/lib/ace/keyboard/vim/maps/util.js @@ -33,7 +33,7 @@ module.exports = { editor.setOverwrite(false); editor.keyBinding.$data.buffer = ""; - editor.keyBinding.$data.state = "insertMode"; + editor.keyBinding.$data.vimState = "insertMode"; this.onVisualMode = false; this.onVisualLineMode = false; if(this.onInsertReplaySequence) { @@ -66,7 +66,7 @@ module.exports = { editor.setOverwrite(true); editor.keyBinding.$data.buffer = ""; - editor.keyBinding.$data.state = "start"; + editor.keyBinding.$data.vimState = "start"; this.onVisualMode = false; this.onVisualLineMode = false; editor._emit("changeStatus"); diff --git a/lib/ace/lib/event.js b/lib/ace/lib/event.js index e904e024..39d115b4 100644 --- a/lib/ace/lib/event.js +++ b/lib/ace/lib/event.js @@ -279,6 +279,14 @@ function normalizeCommandKeys(callback, e, keyCode) { return; } } + + if (useragent.isChromeOS && hashId & 8) { + callback(e, hashId, keyCode); + if (e.defaultPrevented) + return; + else + hashId &= ~8; + } // If there is no hashId and the keyCode is not a function key, then // we don't call the callback as we don't handle a command key here diff --git a/lib/ace/lib/useragent.js b/lib/ace/lib/useragent.js index e56e89a9..e539dae3 100644 --- a/lib/ace/lib/useragent.js +++ b/lib/ace/lib/useragent.js @@ -101,4 +101,6 @@ exports.isIPad = ua.indexOf("iPad") >= 0; exports.isTouchPad = ua.indexOf("TouchPad") >= 0; +exports.isChromeOS = ua.indexOf(" CrOS ") >= 0; + }); diff --git a/lib/ace/mode/_test/tokens_julia.json b/lib/ace/mode/_test/tokens_julia.json index f4ce4eab..5aaef6f9 100644 --- a/lib/ace/mode/_test/tokens_julia.json +++ b/lib/ace/mode/_test/tokens_julia.json @@ -38,7 +38,13 @@ ],[ "start" ],[ - "start" + "start", + ["text","v "], + ["keyword.operator.update.julia","="], + ["text"," "], + ["variable","α"], + ["keyword.operator.transposed-variable.julia","'"], + ["text",";"] ],[ "start", ["keyword.other.julia","function"], diff --git a/lib/ace/mode/julia_highlight_rules.js b/lib/ace/mode/julia_highlight_rules.js index fabec1e3..acff4f4a 100644 --- a/lib/ace/mode/julia_highlight_rules.js +++ b/lib/ace/mode/julia_highlight_rules.js @@ -63,11 +63,11 @@ var JuliaHighlightRules = function() { regex: '(#)(?!\\{)(.*$)'} ], '#function_call': [ { token: [ 'support.function.julia', 'text' ], - regex: '([a-zA-Z0-9_]+!?)(\\w*\\()'} ], + regex: '([a-zA-Z0-9_]+!?)([\\w\\xff-\\u218e\\u2455-\\uffff]*\\()'} ], '#function_decl': [ { token: [ 'keyword.other.julia', 'meta.function.julia', 'entity.name.function.julia', 'meta.function.julia','text' ], - regex: '(function|macro)(\\s*)([a-zA-Z0-9_\\{]+!?)(\\w*)([(\\\\{])'} ], + regex: '(function|macro)(\\s*)([a-zA-Z0-9_\\{]+!?)([\\w\\xff-\\u218e\\u2455-\\uffff]*)([(\\\\{])'} ], '#keyword': [ { token: 'keyword.other.julia', regex: '\\b(?:function|type|immutable|macro|quote|abstract|bitstype|typealias|module|baremodule|new)\\b' }, @@ -75,7 +75,7 @@ var JuliaHighlightRules = function() { regex: '\\b(?:if|else|elseif|while|for|in|begin|let|end|do|try|catch|finally|return|break|continue)\\b' }, { token: 'storage.modifier.variable.julia', regex: '\\b(?:global|local|const|export|import|importall|using)\\b' }, - { token: 'variable.macro.julia', regex: '@\\w+\\b' } ], + { token: 'variable.macro.julia', regex: '@[\\w\\xff-\\u218e\\u2455-\\uffff]+\\b' } ], '#number': [ { token: 'constant.numeric.julia', regex: '\\b0(?:x|X)[0-9a-fA-F]*|(?:\\b[0-9]+\\.?[0-9]*|\\.[0-9]+)(?:(?:e|E)(?:\\+|-)?[0-9]*)?(?:im)?|\\bInf(?:32)?\\b|\\bNaN(?:32)?\\b|\\btrue\\b|\\bfalse\\b' } ], @@ -99,7 +99,7 @@ var JuliaHighlightRules = function() { { token: 'keyword.operator.interpolation.julia', regex: '\\$#?(?=.)' }, { token: [ 'variable', 'keyword.operator.transposed-variable.julia' ], - regex: '(\\w+)((?:\'|\\.\')*\\.?\')' }, + regex: '([\\w\\xff-\\u218e\\u2455-\\uffff]+)((?:\'|\\.\')*\\.?\')' }, { token: 'text', regex: '\\[|\\('}, { token: [ 'text', 'keyword.operator.transposed-matrix.julia' ], @@ -122,10 +122,10 @@ var JuliaHighlightRules = function() { { include: '#string_escaped_char' }, { defaultToken: 'string.quoted.double.julia' } ] }, { token: 'punctuation.definition.string.begin.julia', - regex: '\\b\\w+"', + regex: '\\b[\\w\\xff-\\u218e\\u2455-\\uffff]+"', push: [ { token: 'punctuation.definition.string.end.julia', - regex: '"\\w*', + regex: '"[\\w\\xff-\\u218e\\u2455-\\uffff]*', next: 'pop' }, { include: '#string_custom_escaped_char' }, { defaultToken: 'string.quoted.custom-double.julia' } ] }, diff --git a/lib/ace/requirejs/text.js b/lib/ace/requirejs/text.js index cba62eef..8283c82f 100644 --- a/lib/ace/requirejs/text.js +++ b/lib/ace/requirejs/text.js @@ -35,17 +35,18 @@ (function() { var globalRequire = typeof require != "undefined" && require; - +if (typeof define !== "function") // running in webpack + return module.exports = function(source) { return source; }; + define(function (require, exports, module) { "use strict"; - - exports.load = function (name, req, onLoad, config) { - //Using special require.nodeRequire, something added by r.js. - if (globalRequire && globalRequire.nodeRequire) - onLoad(globalRequire.nodeRequire('fs').readFileSync(req.toUrl(name), 'utf8')); - else + if (globalRequire && globalRequire.nodeRequire) { + module.exports = globalRequire.nodeRequire(require.toUrl("./text_build")); + } else { + exports.load = function(name, req, onLoad, config) { require("../lib/net").get(req.toUrl(name), onLoad); - }; + }; + } }); })(); diff --git a/lib/ace/requirejs/text_build.js b/lib/ace/requirejs/text_build.js new file mode 100644 index 00000000..eb60ead0 --- /dev/null +++ b/lib/ace/requirejs/text_build.js @@ -0,0 +1,60 @@ +/* ***** 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 ***** */ + +/* + * used by r.js during build + */ + +"use strict"; +exports.buildMap = Object.create(null); +exports.load = function(name, req, onLoad, config) { + var buildMap = exports.buildMap; + buildMap[name] = require('fs').readFileSync(req.toUrl(name), 'utf8'); + onLoad(buildMap[name]); +}; +exports.write = function(pluginName, moduleName, write, config) { + if (exports.buildMap[moduleName]) { + var content = exports.jsEscape(exports.buildMap[moduleName]); + write.asModule(pluginName + "!" + moduleName, + "define(function () { return '" + + content + + "';});\n"); + } +}; +exports.jsEscape = function(content) { + return content.replace(/(['\\])/g, '\\$1') + .replace(/[\f]/g, "\\f") + .replace(/[\b]/g, "\\b") + .replace(/[\n]/g, "\\n") + .replace(/[\t]/g, "\\t") + .replace(/[\r]/g, "\\r") + .replace(/[\u2028]/g, "\\u2028") + .replace(/[\u2029]/g, "\\u2029"); +}; diff --git a/lib/ace/theme/ambiance.css b/lib/ace/theme/ambiance.css index c2ac69cf..9f9f7afa 100644 --- a/lib/ace/theme/ambiance.css +++ b/lib/ace/theme/ambiance.css @@ -16,6 +16,10 @@ background: repeat left top; } +.ace-ambiance .ace_gutter-active-line { + background-color: #3F3F3F; +} + .ace-ambiance .ace_fold-widget { text-align: center; } diff --git a/lib/ace/theme/dreamweaver.css b/lib/ace/theme/dreamweaver.css index 6709498c..84865a1c 100644 --- a/lib/ace/theme/dreamweaver.css +++ b/lib/ace/theme/dreamweaver.css @@ -130,6 +130,10 @@ background: rgba(0, 0, 0, 0.07); } +.ace-dreamweaver .ace_gutter-active-line { + background-color : #DCDCDC; +} + .ace-dreamweaver .ace_marker-layer .ace_selected-word { background: rgb(250, 250, 255); border: 1px solid rgb(200, 200, 250); diff --git a/lib/ace/theme/eclipse.css b/lib/ace/theme/eclipse.css index 6615db3a..c83d07a3 100644 --- a/lib/ace/theme/eclipse.css +++ b/lib/ace/theme/eclipse.css @@ -96,10 +96,14 @@ background: rgb(255, 255, 0); } -.ace-eclipse .ace_marker-layer .ace_active-line { +.ace-eclipse .ace_active-line { background: rgb(232, 242, 254); } +.ace-eclipse .ace_gutter-active-line { + background-color : #DADADA; +} + .ace-eclipse .ace_marker-layer .ace_selected-word { border: 1px solid rgb(181, 213, 255); }