Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don't worry, you can still create the pull request.
  • 13 commits
  • 504 files changed
  • 0 commit comments
  • 4 contributors
Commits on Nov 15, 2011
@kenotron kenotron Merge pull request #94 from jmuk/fix-dropbox-storage-errors
Fix the dropbox store errors which was caused by my change.
2118aa3
@kenotron kenotron Merge pull request #95 from jmuk/update-ace-files
Update ace files
aa758c9
Commits on Mar 02, 2012
@miguelcobain miguelcobain I've been struggling with this for hours.
During step 2, the key being used wasn't the correct one. The _createOauthRequest wasn't using the request token secret obtained from step 1.
I'm using Dropbox API v1.
a41853a
Commits on Dec 28, 2012
@kenotron kenotron getting updating dropbox api version and ace version 8016a4f
@kenotron kenotron updated README 200c41e
@kenotron kenotron no utf-8 28fd874
@kenotron kenotron higher version number 054e47b
Commits on Aug 10, 2013
@amit5148 amit5148 Fixed issue for creating file at correct position
Problem: Creating a new file by right clicking a non-root folder creates
the file as its sibling instead of its child.
90bcc8e
Commits on Mar 20, 2014
Ken Chau b d516b13
Commits on Mar 22, 2014
@kenotron kenotron Merge pull request #116 from amit5148/master
Fixed issue for creating file at correct position
1beb208
@kenotron kenotron Merge pull request #103 from miguelcobain/patch-1
Authentication problem fix.
12e9cf2
Commits on Apr 08, 2014
@kenotron kenotron manifest.json c56a234
@kenotron kenotron deleted files 4807216
Showing with 52,106 additions and 3,282 deletions.
  1. +10 −0 README.md
  2. +5 −0 build.js
  3. +9 −3 manifest.json
  4. +23,451 −0 r.js
  5. +1 −7 resources/application.html
  6. +13 −9 resources/css/application.css
  7. +107 −0 src/ace/ace.js
  8. +95 −39 src/ace/anchor.js
  9. +37 −43 src/ace/{test → }/anchor_test.js
  10. +158 −79 src/ace/background_tokenizer.js
  11. +85 −0 src/ace/background_tokenizer_test.js
  12. +121 −0 src/ace/commands/command_manager.js
  13. +199 −0 src/ace/commands/command_manager_test.js
  14. +373 −303 src/ace/commands/default_commands.js
  15. +97 −0 src/ace/commands/multi_select_commands.js
  16. +139 −0 src/ace/config.js
  17. +71 −0 src/ace/config_test.js
  18. BIN  src/ace/css/codefolding-fold-button-states.png
  19. +248 −55 src/ace/css/editor.css
  20. BIN  src/ace/css/expand-marker.png
  21. +0 −51 src/ace/defaults.js
  22. +267 −74 src/ace/document.js
  23. +37 −43 src/ace/{test → }/document_test.js
  24. +1,131 −429 src/ace/edit_session.js
  25. +219 −0 src/ace/edit_session/bracket_match.js
  26. +108 −0 src/ace/edit_session/fold.js
  27. +268 −0 src/ace/edit_session/fold_line.js
  28. +751 −0 src/ace/edit_session/folding.js
  29. +1,017 −0 src/ace/edit_session_test.js
  30. +1,237 −307 src/ace/editor.js
  31. +68 −42 src/ace/{test/change_document_test.js → editor_change_document_test.js}
  32. +68 −58 src/ace/{test/highlight_selected_word_test.js → editor_highlight_selected_word_test.js}
  33. +49 −42 src/ace/{test/navigation_test.js → editor_navigation_test.js}
  34. +126 −67 src/ace/{test/text_edit_test.js → editor_text_edit_test.js}
  35. +22 −0 src/ace/ext/static.css
  36. +88 −0 src/ace/ext/static_highlight.js
  37. +76 −0 src/ace/ext/static_highlight_test.js
  38. +526 −0 src/ace/ext/textarea.js
  39. +375 −0 src/ace/keyboard/emacs.js
  40. +142 −95 src/ace/keyboard/hash_handler.js
  41. +97 −82 src/ace/keyboard/keybinding.js
  42. +0 −97 src/ace/keyboard/keybinding/default_mac.js
  43. +0 −88 src/ace/keyboard/keybinding/default_win.js
  44. +0 −149 src/ace/keyboard/keybinding/emacs.js
  45. +0 −137 src/ace/keyboard/keybinding/vim.js
  46. +50 −47 src/ace/keyboard/state_handler.js
  47. +343 −203 src/ace/keyboard/textinput.js
  48. +151 −0 src/ace/keyboard/vim.js
  49. +586 −0 src/ace/keyboard/vim/commands.js
  50. +94 −0 src/ace/keyboard/vim/maps/aliases.js
  51. +623 −0 src/ace/keyboard/vim/maps/motions.js
  52. +196 −0 src/ace/keyboard/vim/maps/operators.js
  53. +134 −0 src/ace/keyboard/vim/maps/util.js
  54. +42 −0 src/ace/keyboard/vim/registers.js
  55. +151 −80 src/ace/layer/cursor.js
  56. +158 −80 src/ace/layer/gutter.js
  57. +80 −95 src/ace/layer/marker.js
  58. +269 −179 src/ace/layer/text.js
  59. +125 −0 src/ace/layer/text_test.js
  60. +86 −139 src/{pilot → ace/lib}/dom.js
  61. +1,082 −0 src/ace/lib/es5-shim.js
  62. +104 −113 src/{pilot → ace/lib}/event.js
  63. +34 −40 src/{pilot → ace/lib}/event_emitter.js
  64. +65 −0 src/ace/lib/event_emitter_test.js
  65. +4 −3 src/{pilot → ace/lib}/fixoldbrowsers.js
  66. +23 −4 src/{pilot → ace/lib}/keys.js
  67. +204 −0 src/ace/lib/lang.js
  68. +69 −0 src/ace/lib/net.js
  69. +54 −0 src/ace/lib/oop.js
  70. +113 −0 src/ace/lib/regexp.js
  71. +102 −0 src/ace/lib/useragent.js
  72. +8 −0 src/ace/mode/_test/package.json
  73. +144 −0 src/ace/mode/_test/test_highlight_rules.js
  74. +111 −0 src/ace/mode/_test/text_asciidoc.txt
  75. +52 −0 src/ace/mode/_test/text_javascript.txt
  76. +294 −0 src/ace/mode/_test/tokens_abap.json
  77. +729 −0 src/ace/mode/_test/tokens_asciidoc.json
  78. +160 −0 src/ace/mode/_test/tokens_c9search.json
  79. +273 −0 src/ace/mode/_test/tokens_c_cpp.json
  80. +219 −0 src/ace/mode/_test/tokens_clojure.json
  81. +190 −0 src/ace/mode/_test/tokens_coffee.json
  82. +40 −0 src/ace/mode/_test/tokens_coldfusion.json
  83. +42 −0 src/ace/mode/_test/tokens_csharp.json
  84. +231 −0 src/ace/mode/_test/tokens_css.json
  85. +537 −0 src/ace/mode/_test/tokens_dart.json
  86. +729 −0 src/ace/mode/_test/tokens_diff.json
  87. +185 −0 src/ace/mode/_test/tokens_glsl.json
  88. +357 −0 src/ace/mode/_test/tokens_golang.json
  89. +523 −0 src/ace/mode/_test/tokens_groovy.json
  90. +280 −0 src/ace/mode/_test/tokens_haml.json
  91. +195 −0 src/ace/mode/_test/tokens_haxe.json
  92. +150 −0 src/ace/mode/_test/tokens_html.json
  93. +309 −0 src/ace/mode/_test/tokens_jade.json
  94. +139 −0 src/ace/mode/_test/tokens_java.json
  95. +545 −0 src/ace/mode/_test/tokens_javascript.json
  96. +611 −0 src/ace/mode/_test/tokens_json.json
  97. +569 −0 src/ace/mode/_test/tokens_jsp.json
  98. +79 −0 src/ace/mode/_test/tokens_jsx.json
  99. +194 −0 src/ace/mode/_test/tokens_latex.json
  100. +288 −0 src/ace/mode/_test/tokens_less.json
  101. +696 −0 src/ace/mode/_test/tokens_liquid.json
  102. +314 −0 src/ace/mode/_test/tokens_lisp.json
  103. +444 −0 src/ace/mode/_test/tokens_lua.json
  104. +827 −0 src/ace/mode/_test/tokens_luapage.json
  105. +21 −0 src/ace/mode/_test/tokens_lucene.json
  106. +1,191 −0 src/ace/mode/_test/tokens_markdown.json
  107. +1,080 −0 src/ace/mode/_test/tokens_objectivec.json
  108. +252 −0 src/ace/mode/_test/tokens_ocaml.json
  109. +309 −0 src/ace/mode/_test/tokens_perl.json
  110. +1,015 −0 src/ace/mode/_test/tokens_pgsql.json
  111. +188 −0 src/ace/mode/_test/tokens_php.json
  112. +254 −0 src/ace/mode/_test/tokens_powershell.json
  113. +203 −0 src/ace/mode/_test/tokens_python.json
  114. +296 −0 src/ace/mode/_test/tokens_r.json
Sorry, we could not display the entire diff because too many files (504) changed.
View
10 README.md
@@ -25,6 +25,16 @@ Contributors
Changelog
---------
+### 0.8.3 ###
+* What happened to 0.8.2?? Dunno
+* Fixed the manifest.json
+
+### 0.8.1 ###
+* temporarily disabling the other store methods
+* deleted unused deps
+* updated Ace version
+* updated to use dropbox-js project
+
### 0.8.0 ###
* Added localstorage support (jmuk)
* Added extension based storage engines support (jmuk)
View
5 build.js
@@ -0,0 +1,5 @@
+({
+ baseUrl: "src",
+ name: "sourcekit/application",
+ out: "src/sourcekit.js"
+})
View
12 manifest.json
@@ -1,6 +1,7 @@
-{
+{
+ "manifest_version": 2,
"name": "SourceKit",
- "version": "0.8.0",
+ "version": "0.8.3",
"incognito": "split",
"icons": {
"128": "icons/icon_128.png",
@@ -11,7 +12,12 @@
"local_path": "resources/application.html"
}
},
- "background_page": "resources/background.html",
+ "web_accessible_resources": [
+ "resources/*",
+ "src/*",
+ "icons/*"
+ ],
+ "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"permissions": [
"tabs",
"notifications",
View
23,451 r.js
23,451 additions, 0 deletions not shown
View
8 resources/application.html
@@ -7,13 +7,6 @@
<link rel="stylesheet" href="css/themes/claro/claro.css" />
<link rel="stylesheet" href="css/application.css" />
<script src="../src/dojo/dojo.js.uncompressed.js" djConfig="parseOnLoad:true"></script>
- <script type="text/javascript">
- dojo.require('dijit.layout.BorderContainer');
- dojo.require('dijit.layout.ContentPane');
- dojo.require('dijit.layout.TabContainer');
- dojo.require('dijit.Dialog');
- dojo.require('dijit.form.Select');
- </script>
</head>
<body class="claro">
<div dojoType="dijit.Dialog" id="optionsDialog" title="Options">
@@ -47,6 +40,7 @@
</div>
</div>
<div id="editorContainer"></div>
+ <script src="../src/dropbox/dropbox.min.js"></script>
<script src="../src/require.js"></script>
<script src="../src/boot.js"></script>
</body>
View
22 resources/css/application.css
@@ -10,30 +10,34 @@ body, html { width:100%; height:100%; margin:0; padding:0; overflow: hidden; }
#borderLeft {
width: 200px;
- margin: 5px 0 5px 5px;
- padding: 0;
- border: #B5BCC7 solid 1px;
+ background: #eee;
+}
+
+.dijitTreeRow {
+ background-image: none !important;
}
#borderCenter {
padding: 0 5px 5px 0;
-
}
#introContainer {
- background: #ddd;
+ background: #111;
height: 100%;
width: 100%;
+
+ display: -webkit-flex;
+ -webkit-justify-content: center;
+ -webkit-align-items: center;
+ -webkit-flex-direction: column;
}
#introContainer h1 {
font-size: 50px;
font-family: helvetica;
font-weight: bold;
- color: #999;
- margin: 0 auto 0 auto;
- padding: 50px 0 0 0;
- text-shadow: 1px 1px 1px white;
+ color: #111;
+ text-shadow: 1px 1px 3px #333;
text-align: center;
}
View
107 src/ace/ace.js
@@ -0,0 +1,107 @@
+/* ***** 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 ***** */
+
+/**
+ * The main class required to set up an Ace instance in the browser.
+ *
+ * @class Ace
+ **/
+
+define(function(require, exports, module) {
+"use strict";
+
+require("./lib/fixoldbrowsers");
+
+var dom = require("./lib/dom");
+var event = require("./lib/event");
+
+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("./mode/folding/fold_mode");
+exports.config = require("./config");
+
+/**
+ * Provides access to require in packed noconflict mode
+ * @param {String} moduleName
+ * @returns {Object}
+ *
+ **/
+exports.require = require;
+
+/**
+ * Embeds the Ace editor into the DOM, at the element provided by `el`.
+ * @param {String | DOMElement} el Either the id of an element, or the element itself
+ *
+ **/
+exports.edit = function(el) {
+ if (typeof(el) == "string") {
+ var _id = el;
+ var el = document.getElementById(_id);
+ if (!el)
+ throw "ace.edit can't find div #" + _id;
+ }
+
+ if (el.env && el.env.editor instanceof Editor)
+ return el.env.editor;
+
+ var doc = exports.createEditSession(dom.getInnerText(el));
+ el.innerHTML = '';
+
+ var editor = new Editor(new Renderer(el));
+ new MultiSelect(editor);
+ editor.setSession(doc);
+
+ var env = {
+ document: doc,
+ editor: editor,
+ onResize: editor.resize.bind(editor)
+ };
+ event.addListener(window, "resize", env.onResize);
+ el.env = editor.env = env;
+ return editor;
+};
+
+
+exports.createEditSession = function(text, mode) {
+ var doc = new EditSession(text, doc);
+ doc.setUndoManager(new UndoManager());
+ return doc;
+}
+exports.EditSession = EditSession;
+exports.UndoManager = UndoManager;
+});
View
134 src/ace/anchor.js
@@ -1,49 +1,56 @@
/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ * Distributed under the BSD license:
*
- * 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):
- * Fabian Jakobs <fabian AT ajax DOT org>
- *
- * 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.
+ * 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 ***** */
define(function(require, exports, module) {
+"use strict";
-var oop = require("pilot/oop");
-var EventEmitter = require("pilot/event_emitter").EventEmitter;
+var oop = require("./lib/oop");
+var EventEmitter = require("./lib/event_emitter").EventEmitter;
/**
- * An Anchor is a floating pointer in the document. Whenever text is inserted or
- * deleted before the cursor, the position of the cursor is updated
- */
+ *
+ * Defines the floating pointer in the document. Whenever text is inserted or deleted before the cursor, the position of the cursor is updated.
+ *
+ * @class Anchor
+ **/
+
+/**
+ * Creates a new `Anchor` and associates it with a document.
+ *
+ * @param {Document} doc The document to associate with the anchor
+ * @param {Number} row The starting row position
+ * @param {Number} column The starting column position
+ *
+ * @constructor
+ **/
+
var Anchor = exports.Anchor = function(doc, row, column) {
this.document = doc;
@@ -60,14 +67,40 @@ var Anchor = exports.Anchor = function(doc, row, column) {
oop.implement(this, EventEmitter);
+ /**
+ * Returns an object identifying the `row` and `column` position of the current anchor.
+ * @returns {Object}
+ **/
+
this.getPosition = function() {
return this.$clipPositionToDocument(this.row, this.column);
};
-
+
+ /**
+ *
+ * Returns the current document.
+ * @returns {Document}
+ **/
+
this.getDocument = function() {
return this.document;
};
+ /**
+ * Fires whenever the anchor position changes.
+ *
+ * Both of these objects have a `row` and `column` property corresponding to the position.
+ *
+ * Events that can trigger this function include [[Anchor.setPosition `setPosition()`]].
+ *
+ * @event change
+ * @param {Object} e An object containing information about the anchor position. It has two properties:
+ * - `old`: An object describing the old Anchor position
+ * - `value`: An object describing the new Anchor position
+ *
+ *
+ **/
+
this.onChange = function(e) {
var delta = e.data;
var range = delta.range;
@@ -133,6 +166,16 @@ var Anchor = exports.Anchor = function(doc, row, column) {
this.setPosition(row, column, true);
};
+ /**
+ * Sets the anchor position to the specified row and column. If `noClip` is `true`, the position is not clipped.
+ * @param {Number} row The row index to move the anchor to
+ * @param {Number} column The column index to move the anchor to
+ * @param {Boolean} noClip Identifies if you want the position to be clipped
+ *
+ *
+ *
+ **/
+
this.setPosition = function(row, column, noClip) {
var pos;
if (noClip) {
@@ -155,16 +198,29 @@ var Anchor = exports.Anchor = function(doc, row, column) {
this.row = pos.row;
this.column = pos.column;
- this._dispatchEvent("change", {
+ this._emit("change", {
old: old,
value: pos
});
};
+ /**
+ * When called, the `'change'` event listener is removed.
+ *
+ **/
+
this.detach = function() {
this.document.removeEventListener("change", this.$onChange);
};
+ /**
+ * Clips the anchor position to the specified row and column.
+ * @param {Number} row The row index to clip the anchor to
+ * @param {Number} column The column index to clip the anchor to
+ *
+ *
+ *
+ **/
this.$clipPositionToDocument = function(row, column) {
var pos = {};
View
80 src/ace/test/anchor_test.js → src/ace/anchor_test.js
@@ -1,49 +1,46 @@
/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ * Distributed under the BSD license:
*
- * 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):
- * Fabian Jakobs <fabian AT ajax DOT org>
- *
- * 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.
+ * 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 ***** */
+if (typeof process !== "undefined") {
+ require("amd-loader");
+}
+
define(function(require, exports, module) {
-
-var Document = require("ace/document").Document;
-var Anchor = require("ace/anchor").Anchor;
-var Range = require("ace/range").Range;
-var assert = require("./assertions");
-var async = require("asyncjs");
+"use strict";
-var Test = {
+var Document = require("./document").Document;
+var Anchor = require("./anchor").Anchor;
+var Range = require("./range").Range;
+var assert = require("./test/assertions");
+
+module.exports = {
"test create anchor" : function() {
var doc = new Document("juhu");
@@ -173,11 +170,8 @@ var Test = {
}
};
-module.exports = require("asyncjs/test").testcase(Test);
-
});
if (typeof module !== "undefined" && module === require.main) {
- require("../../../support/paths");
- exports.exec()
+ require("asyncjs").test.testcase(module.exports).exec()
}
View
237 src/ace/background_tokenizer.js
@@ -1,48 +1,66 @@
/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ * Distributed under the BSD license:
*
- * 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):
- * Fabian Jakobs <fabian AT ajax DOT org>
- *
- * 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.
+ * 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 ***** */
define(function(require, exports, module) {
+"use strict";
+
+var oop = require("./lib/oop");
+var EventEmitter = require("./lib/event_emitter").EventEmitter;
-var oop = require("pilot/oop");
-var EventEmitter = require("pilot/event_emitter").EventEmitter;
+// tokenizing lines longer than this makes editor very slow
+var MAX_LINE_LENGTH = 5000;
+
+/**
+ *
+ *
+ * Tokenizes the current [[Document `Document`]] in the background, and caches the tokenized rows for future use.
+ *
+ * If a certain row is changed, everything below that row is re-tokenized.
+ *
+ * @class BackgroundTokenizer
+ **/
+
+/**
+ * Creates a new `BackgroundTokenizer` object.
+ * @param {Tokenizer} tokenizer The tokenizer to use
+ * @param {Editor} editor The editor to associate with
+ *
+ *
+ *
+ * @constructor
+ **/
var BackgroundTokenizer = function(tokenizer, editor) {
- this.running = false;
+ this.running = false;
this.lines = [];
+ this.states = [];
this.currentLine = 0;
this.tokenizer = tokenizer;
@@ -59,11 +77,12 @@ var BackgroundTokenizer = function(tokenizer, editor) {
var len = doc.getLength();
while (self.currentLine < len) {
- self.lines[self.currentLine] = self.$tokenizeRows(self.currentLine, self.currentLine)[0];
- self.currentLine++;
+ self.$tokenizeRow(self.currentLine);
+ while (self.lines[self.currentLine])
+ self.currentLine++;
// only check every 5 lines
- processedLines += 1;
+ processedLines ++;
if ((processedLines % 5 == 0) && (new Date() - workerStart) > 20) {
self.fireUpdateEvent(startLine, self.currentLine-1);
self.running = setTimeout(self.$worker, 20);
@@ -81,92 +100,152 @@ var BackgroundTokenizer = function(tokenizer, editor) {
oop.implement(this, EventEmitter);
+ /**
+ * Sets a new tokenizer for this object.
+ *
+ * @param {Tokenizer} tokenizer The new tokenizer to use
+ *
+ **/
this.setTokenizer = function(tokenizer) {
this.tokenizer = tokenizer;
this.lines = [];
+ this.states = [];
this.start(0);
};
+ /**
+ * Sets a new document to associate with this object.
+ * @param {Document} doc The new document to associate with
+ **/
this.setDocument = function(doc) {
this.doc = doc;
this.lines = [];
+ this.states = [];
this.stop();
};
+ /**
+ * Fires whenever the background tokeniziers between a range of rows are going to be updated.
+ *
+ * @event update
+ * @param {Object} e An object containing two properties, `first` and `last`, which indicate the rows of the region being updated.
+ *
+ **/
+ /**
+ * Emits the `'update'` event. `firstRow` and `lastRow` are used to define the boundaries of the region to be updated.
+ * @param {Number} firstRow The starting row region
+ * @param {Number} lastRow The final row region
+ *
+ **/
this.fireUpdateEvent = function(firstRow, lastRow) {
var data = {
first: firstRow,
last: lastRow
};
- this._dispatchEvent("update", {data: data});
+ this._emit("update", {data: data});
};
+ /**
+ * Starts tokenizing at the row indicated.
+ *
+ * @param {Number} startRow The row to start at
+ *
+ **/
this.start = function(startRow) {
- this.currentLine = Math.min(startRow || 0, this.currentLine,
- this.doc.getLength());
+ this.currentLine = Math.min(startRow || 0, this.currentLine, this.doc.getLength());
// remove all cached items below this line
this.lines.splice(this.currentLine, this.lines.length);
+ this.states.splice(this.currentLine, this.states.length);
this.stop();
// pretty long delay to prevent the tokenizer from interfering with the user
this.running = setTimeout(this.$worker, 700);
};
+ this.$updateOnChange = function(delta) {
+ var range = delta.range;
+ var startRow = range.start.row;
+ var len = range.end.row - startRow;
+
+ if (len === 0) {
+ this.lines[startRow] = null;
+ } else if (delta.action == "removeText" || delta.action == "removeLines") {
+ this.lines.splice(startRow, len + 1, null);
+ this.states.splice(startRow, len + 1, null);
+ } else {
+ var args = Array(len + 1);
+ args.unshift(startRow, 1);
+ this.lines.splice.apply(this.lines, args);
+ this.states.splice.apply(this.states, args);
+ }
+
+ this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength());
+
+ this.stop();
+ // pretty long delay to prevent the tokenizer from interfering with the user
+ this.running = setTimeout(this.$worker, 700);
+ };
+
+ /**
+ * Stops tokenizing.
+ *
+ **/
this.stop = function() {
if (this.running)
clearTimeout(this.running);
this.running = false;
};
- this.getTokens = function(firstRow, lastRow) {
- return this.$tokenizeRows(firstRow, lastRow);
+ /**
+ * Gives list of tokens of the row. (tokens are cached)
+ *
+ * @param {Number} row The row to get tokens at
+ *
+ *
+ *
+ **/
+ this.getTokens = function(row) {
+ return this.lines[row] || this.$tokenizeRow(row);
};
+ /**
+ * [Returns the state of tokenization at the end of a row.]{: #BackgroundTokenizer.getState}
+ *
+ * @param {Number} row The row to get state at
+ **/
this.getState = function(row) {
- return this.$tokenizeRows(row, row)[0].state;
+ if (this.currentLine == row)
+ this.$tokenizeRow(row);
+ return this.states[row] || "start";
};
- this.$tokenizeRows = function(firstRow, lastRow) {
- if (!this.doc)
- return [];
-
- var rows = [];
-
- // determine start state
- var state = "start";
- var doCache = false;
- if (firstRow > 0 && this.lines[firstRow - 1]) {
- state = this.lines[firstRow - 1].state;
- doCache = true;
- } else if (firstRow == 0) {
- state = "start";
- doCache = true;
- } else if (this.lines.length > 0) {
- // Guess that we haven't changed state.
- state = this.lines[this.lines.length-1].state;
- }
+ this.$tokenizeRow = function(row) {
+ var line = this.doc.getLine(row);
+ var state = this.states[row - 1];
- var lines = this.doc.getLines(firstRow, lastRow);
- for (var row=firstRow; row<=lastRow; row++) {
- if (!this.lines[row]) {
- var tokens = this.tokenizer.getLineTokens(lines[row-firstRow] || "", state);
- var state = tokens.state;
- rows.push(tokens);
+ if (line.length > MAX_LINE_LENGTH) {
+ var overflow = {value: line.substr(MAX_LINE_LENGTH), type: "text"};
+ line = line.slice(0, MAX_LINE_LENGTH);
+ }
+ var data = this.tokenizer.getLineTokens(line, state);
+ if (overflow) {
+ data.tokens.push(overflow);
+ data.state = "start";
+ }
- if (doCache) {
- this.lines[row] = tokens;
- }
- }
- else {
- var tokens = this.lines[row];
- state = tokens.state;
- rows.push(tokens);
- }
+ if (this.states[row] !== data.state) {
+ this.states[row] = data.state;
+ this.lines[row + 1] = null;
+ if (this.currentLine > row + 1)
+ this.currentLine = row + 1;
+ } else if (this.currentLine == row) {
+ this.currentLine = row + 1;
}
- return rows;
+
+ return this.lines[row] = data.tokens;
};
}).call(BackgroundTokenizer.prototype);
View
85 src/ace/background_tokenizer_test.js
@@ -0,0 +1,85 @@
+/* ***** 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 ***** */
+
+if (typeof process !== "undefined") {
+ require("amd-loader");
+}
+
+define(function(require, exports, module) {
+"use strict";
+
+var EditSession = require("./edit_session").EditSession;
+var JavaScriptMode = require("./mode/javascript").Mode;
+var Range = require("./range").Range;
+var assert = require("./test/assertions");
+
+function forceTokenize(session){
+ for (var i = 0, l = session.getLength(); i < l; i++)
+ session.getTokens(i)
+}
+
+function testStates(session, states) {
+ for (var i = 0, l = session.getLength(); i < l; i++)
+ assert.equal(session.bgTokenizer.states[i], states[i])
+ assert.ok(l == states.length)
+}
+
+module.exports = {
+
+ "test background tokenizer update on session change" : function() {
+ var doc = new EditSession([
+ "/*",
+ "*/",
+ "var juhu"
+ ]);
+ doc.setMode("./mode/javascript")
+
+ forceTokenize(doc)
+ testStates(doc, ["comment", "start", "start"])
+
+ doc.remove(new Range(0,2,1,2))
+ testStates(doc, [null, "start"])
+
+ forceTokenize(doc)
+ testStates(doc, ["comment", "comment"])
+
+ doc.insert({row:0, column:2}, "\n*/")
+ testStates(doc, [undefined, undefined, "comment"])
+
+ forceTokenize(doc)
+ testStates(doc, ["comment", "start", "start"])
+ }
+};
+
+});
+
+if (typeof module !== "undefined" && module === require.main) {
+ require("asyncjs").test.testcase(module.exports).exec()
+}
View
121 src/ace/commands/command_manager.js
@@ -0,0 +1,121 @@
+define(function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var HashHandler = require("../keyboard/hash_handler").HashHandler;
+var EventEmitter = require("../lib/event_emitter").EventEmitter;
+
+/**
+ * @class CommandManager
+ *
+ *
+ **/
+
+/**
+ * new CommandManager(platform, commands)
+ * @param {String} platform Identifier for the platform; must be either `'mac'` or `'win'`
+ * @param {Array} commands A list of commands
+ *
+ *
+ *
+ *
+ **/
+
+var CommandManager = function(platform, commands) {
+ this.platform = platform;
+ this.commands = this.byName = {};
+ this.commmandKeyBinding = {};
+
+ this.addCommands(commands);
+
+ this.setDefaultHandler("exec", function(e) {
+ return e.command.exec(e.editor, e.args || {});
+ });
+};
+
+oop.inherits(CommandManager, HashHandler);
+
+(function() {
+
+ oop.implement(this, EventEmitter);
+
+ this.exec = function(command, editor, args) {
+ if (typeof command === 'string')
+ command = this.commands[command];
+
+ if (!command)
+ return false;
+
+ if (editor && editor.$readOnly && !command.readOnly)
+ return false;
+
+ var retvalue = this._emit("exec", {
+ editor: editor,
+ command: command,
+ args: args
+ });
+
+ return retvalue === false ? false : true;
+ };
+
+ this.toggleRecording = function(editor) {
+ if (this.$inReplay)
+ return;
+
+ editor && editor._emit("changeStatus");
+ if (this.recording) {
+ this.macro.pop();
+ this.removeEventListener("exec", this.$addCommandToMacro);
+
+ if (!this.macro.length)
+ this.macro = this.oldMacro;
+
+ return this.recording = false;
+ }
+ if (!this.$addCommandToMacro) {
+ this.$addCommandToMacro = function(e) {
+ this.macro.push([e.command, e.args]);
+ }.bind(this);
+ }
+
+ this.oldMacro = this.macro;
+ this.macro = [];
+ this.on("exec", this.$addCommandToMacro);
+ return this.recording = true;
+ };
+
+ this.replay = function(editor) {
+ if (this.$inReplay || !this.macro)
+ return;
+
+ if (this.recording)
+ return this.toggleRecording(editor);
+
+ try {
+ this.$inReplay = true;
+ this.macro.forEach(function(x) {
+ if (typeof x == "string")
+ this.exec(x, editor);
+ else
+ this.exec(x[0], editor, x[1]);
+ }, this);
+ } finally {
+ this.$inReplay = false;
+ }
+ };
+
+ this.trimMacro = function(m) {
+ return m.map(function(x){
+ if (typeof x[0] != "string")
+ x[0] = x[0].name;
+ if (!x[1])
+ x = x[0];
+ return x;
+ });
+ };
+
+}).call(CommandManager.prototype);
+
+exports.CommandManager = CommandManager;
+
+});
View
199 src/ace/commands/command_manager_test.js
@@ -0,0 +1,199 @@
+/* ***** 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 ***** */
+
+if (typeof process !== "undefined") {
+ require("amd-loader");
+}
+
+define(function(require, exports, module) {
+"use strict";
+
+var CommandManager = require("./command_manager").CommandManager;
+var keys = require("../lib/keys");
+var assert = require("../test/assertions");
+
+module.exports = {
+
+ setUp: function() {
+ this.command = {
+ name: "gotoline",
+ bindKey: {
+ mac: "Command-L",
+ win: "Ctrl-L"
+ },
+ called: false,
+ exec: function(editor) { this.called = true; }
+ };
+
+ this.cm = new CommandManager("mac", [this.command]);
+ },
+
+ "test: register command": function() {
+ this.cm.exec("gotoline");
+ assert.ok(this.command.called);
+ },
+
+ "test: mac hotkeys": function() {
+ var command = this.cm.findKeyCommand(keys.KEY_MODS.command, "l");
+ assert.equal(command, this.command);
+
+ var command = this.cm.findKeyCommand(keys.KEY_MODS.ctrl, "l");
+ assert.equal(command, undefined);
+ },
+
+ "test: win hotkeys": function() {
+ var cm = new CommandManager("win", [this.command]);
+
+ var command = cm.findKeyCommand(keys.KEY_MODS.command, "l");
+ assert.equal(command, undefined);
+
+ var command = cm.findKeyCommand(keys.KEY_MODS.ctrl, "l");
+ assert.equal(command, this.command);
+ },
+
+ "test: remove command by object": function() {
+ this.cm.removeCommand(this.command);
+
+ this.cm.exec("gotoline");
+ assert.ok(!this.command.called);
+
+ var command = this.cm.findKeyCommand(keys.KEY_MODS.command, "l");
+ assert.equal(command, null);
+ },
+
+ "test: remove command by name": function() {
+ this.cm.removeCommand("gotoline");
+
+ this.cm.exec("gotoline");
+ assert.ok(!this.command.called);
+
+ var command = this.cm.findKeyCommand(keys.KEY_MODS.command, "l");
+ assert.equal(command, null);
+ },
+
+ "test: adding a new command with the same name as an existing one should remove the old one first": function() {
+ var command = {
+ name: "gotoline",
+ bindKey: {
+ mac: "Command-L",
+ win: "Ctrl-L"
+ },
+ called: false,
+ exec: function(editor) { this.called = true; }
+ };
+ this.cm.addCommand(command);
+
+ this.cm.exec("gotoline");
+ assert.ok(command.called);
+ assert.ok(!this.command.called);
+
+ assert.equal(this.cm.findKeyCommand(keys.KEY_MODS.command, "l"), command);
+ },
+
+ "test: adding commands and recording a macro": function() {
+ var called = "";
+ this.cm.addCommands({
+ togglerecording: function(editor) {
+ editor.cm.toggleRecording(editor);
+ },
+ replay: function(editor) {
+ editor.cm.replay();
+ },
+ cm1: function(editor, arg) {
+ called += "1" + (arg || "");
+ },
+ cm2: function(editor) {
+ called += "2";
+ }
+ });
+
+
+ var statusUpdateEmitted = false;
+ this._emit = function() {statusUpdateEmitted = true};
+
+ this.cm.exec("togglerecording", this);
+ assert.ok(this.cm.recording);
+ assert.ok(statusUpdateEmitted);
+
+ this.cm.exec("cm1", this, "-");
+ this.cm.exec("cm2");
+ this.cm.exec("replay", this);
+ assert.ok(!this.cm.recording);
+ assert.equal(called, "1-2");
+
+ called = "";
+ this.cm.exec("replay", this);
+ assert.equal(called, "1-2");
+ },
+
+ "test: bindkeys": function() {
+ this.cm.bindKeys({
+ "Ctrl-L|Command-C": "cm1",
+ "Ctrl-R": "cm2"
+ });
+
+ var command = this.cm.findKeyCommand(keys.KEY_MODS.command, "c");
+ assert.equal(command, "cm1");
+
+ var command = this.cm.findKeyCommand(keys.KEY_MODS.ctrl, "r");
+ assert.equal(command, "cm2");
+
+ this.cm.bindKeys({
+ "Ctrl-R": null
+ });
+
+ var command = this.cm.findKeyCommand(keys.KEY_MODS.ctrl, "r");
+ assert.equal(command, null);
+ },
+
+ "test: binding keys without modifiers": function() {
+ this.cm.bindKeys({
+ "R": "cm1",
+ "Shift-r": "cm2",
+ "Return": "cm4",
+ "Enter": "cm3"
+ });
+
+ var command = this.cm.findKeyCommand(-1, "r");
+ assert.equal(command, "cm1");
+
+ var command = this.cm.findKeyCommand(-1, "R");
+ assert.equal(command, "cm2");
+
+ var command = this.cm.findKeyCommand(0, "return");
+ assert.equal(command, "cm3");
+ }
+};
+
+});
+
+if (typeof module !== "undefined" && module === require.main) {
+ require("asyncjs").test.testcase(module.exports).exec();
+}
View
676 src/ace/commands/default_commands.js
@@ -1,397 +1,467 @@
-/* vim:ts=4:sts=4:sw=4:
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
*
- * 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):
- * Fabian Jakobs <fabian AT ajax DOT org>
- * Julian Viereck <julian.viereck@gmail.com>
- * Mihai Sucan <mihai.sucan@gmail.com>
- *
- * 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.
+ * 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 ***** */
define(function(require, exports, module) {
+"use strict";
-var lang = require("pilot/lang");
-var canon = require("pilot/canon");
+var lang = require("../lib/lang");
function bindKey(win, mac) {
return {
win: win,
- mac: mac,
- sender: "editor"
+ mac: mac
};
}
-canon.addCommand({
- name: "null",
- exec: function(env, args, request) { }
-});
-
-canon.addCommand({
+exports.commands = [{
name: "selectall",
bindKey: bindKey("Ctrl-A", "Command-A"),
- exec: function(env, args, request) { env.editor.selectAll(); }
-});
-canon.addCommand({
- name: "removeline",
- bindKey: bindKey("Ctrl-D", "Command-D"),
- exec: function(env, args, request) { env.editor.removeLines(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.selectAll(); },
+ readOnly: true
+}, {
+ name: "centerselection",
+ bindKey: bindKey(null, "Ctrl-L"),
+ exec: function(editor) { editor.centerSelection(); },
+ readOnly: true
+}, {
name: "gotoline",
bindKey: bindKey("Ctrl-L", "Command-L"),
- exec: function(env, args, request) {
- var line = parseInt(prompt("Enter line number:"));
+ exec: function(editor) {
+ var line = parseInt(prompt("Enter line number:"), 10);
if (!isNaN(line)) {
- env.editor.gotoLine(line);
+ editor.gotoLine(line);
}
- }
-});
-canon.addCommand({
- name: "togglecomment",
- bindKey: bindKey("Ctrl-7", "Command-7"),
- exec: function(env, args, request) { env.editor.toggleCommentLines(); }
-});
-canon.addCommand({
+ },
+ readOnly: true
+}, {
+ name: "fold",
+ bindKey: bindKey("Alt-L|Ctrl-F1", "Command-Alt-L|Command-F1"),
+ exec: function(editor) { editor.session.toggleFold(false); },
+ readOnly: true
+}, {
+ name: "unfold",
+ bindKey: bindKey("Alt-Shift-L|Ctrl-Shift-F1", "Command-Alt-Shift-L|Command-Shift-F1"),
+ exec: function(editor) { editor.session.toggleFold(true); },
+ readOnly: true
+}, {
+ name: "foldall",
+ bindKey: bindKey("Alt-0", "Command-Option-0"),
+ exec: function(editor) { editor.session.foldAll(); },
+ readOnly: true
+}, {
+ name: "unfoldall",
+ bindKey: bindKey("Alt-Shift-0", "Command-Option-Shift-0"),
+ exec: function(editor) { editor.session.unfold(); },
+ readOnly: true
+}, {
name: "findnext",
bindKey: bindKey("Ctrl-K", "Command-G"),
- exec: function(env, args, request) { env.editor.findNext(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.findNext(); },
+ readOnly: true
+}, {
name: "findprevious",
bindKey: bindKey("Ctrl-Shift-K", "Command-Shift-G"),
- exec: function(env, args, request) { env.editor.findPrevious(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.findPrevious(); },
+ readOnly: true
+}, {
name: "find",
bindKey: bindKey("Ctrl-F", "Command-F"),
- exec: function(env, args, request) {
- var needle = prompt("Find:", env.editor.getCopyText());
- env.editor.find(needle);
- }
-});
-canon.addCommand({
- name: "replace",
- bindKey: bindKey("Ctrl-R", "Command-Option-F"),
- exec: function(env, args, request) {
- var needle = prompt("Find:", env.editor.getCopyText());
- if (!needle)
- return;
- var replacement = prompt("Replacement:");
- if (!replacement)
- return;
- env.editor.replace(replacement, {needle: needle});
- }
-});
-canon.addCommand({
- name: "replaceall",
- bindKey: bindKey("Ctrl-Shift-R", "Command-Shift-Option-F"),
- exec: function(env, args, request) {
- var needle = prompt("Find:");
- if (!needle)
- return;
- var replacement = prompt("Replacement:");
- if (!replacement)
- return;
- env.editor.replaceAll(replacement, {needle: needle});
- }
-});
-canon.addCommand({
- name: "undo",
- bindKey: bindKey("Ctrl-Z", "Command-Z"),
- exec: function(env, args, request) { env.editor.undo(); }
-});
-canon.addCommand({
- name: "redo",
- bindKey: bindKey("Ctrl-Shift-Z|Ctrl-Y", "Command-Shift-Z|Command-Y"),
- exec: function(env, args, request) { env.editor.redo(); }
-});
-canon.addCommand({
+ exec: function(editor) {
+ var needle = prompt("Find:", editor.getCopyText());
+ editor.find(needle);
+ },
+ readOnly: true
+}, {
name: "overwrite",
- bindKey: bindKey("Insert", "Insert"),
- exec: function(env, args, request) { env.editor.toggleOverwrite(); }
-});
-canon.addCommand({
- name: "copylinesup",
- bindKey: bindKey("Ctrl-Alt-Up", "Command-Option-Up"),
- exec: function(env, args, request) { env.editor.copyLinesUp(); }
-});
-canon.addCommand({
- name: "movelinesup",
- bindKey: bindKey("Alt-Up", "Option-Up"),
- exec: function(env, args, request) { env.editor.moveLinesUp(); }
-});
-canon.addCommand({
+ bindKey: "Insert",
+ exec: function(editor) { editor.toggleOverwrite(); },
+ readOnly: true
+}, {
name: "selecttostart",
- bindKey: bindKey("Ctrl-Shift-Home|Alt-Shift-Up", "Command-Shift-Up"),
- exec: function(env, args, request) { env.editor.getSelection().selectFileStart(); }
-});
-canon.addCommand({
+ bindKey: bindKey("Ctrl-Shift-Home", "Command-Shift-Up"),
+ exec: function(editor) { editor.getSelection().selectFileStart(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "gotostart",
- bindKey: bindKey("Ctrl-Home|Ctrl-Up", "Command-Home|Command-Up"),
- exec: function(env, args, request) { env.editor.navigateFileStart(); }
-});
-canon.addCommand({
+ bindKey: bindKey("Ctrl-Home", "Command-Home|Command-Up"),
+ exec: function(editor) { editor.navigateFileStart(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "selectup",
bindKey: bindKey("Shift-Up", "Shift-Up"),
- exec: function(env, args, request) { env.editor.getSelection().selectUp(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.getSelection().selectUp(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "golineup",
bindKey: bindKey("Up", "Up|Ctrl-P"),
- exec: function(env, args, request) { env.editor.navigateUp(args.times); }
-});
-canon.addCommand({
- name: "copylinesdown",
- bindKey: bindKey("Ctrl-Alt-Down", "Command-Option-Down"),
- exec: function(env, args, request) { env.editor.copyLinesDown(); }
-});
-canon.addCommand({
- name: "movelinesdown",
- bindKey: bindKey("Alt-Down", "Option-Down"),
- exec: function(env, args, request) { env.editor.moveLinesDown(); }
-});
-canon.addCommand({
+ exec: function(editor, args) { editor.navigateUp(args.times); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "selecttoend",
- bindKey: bindKey("Ctrl-Shift-End|Alt-Shift-Down", "Command-Shift-Down"),
- exec: function(env, args, request) { env.editor.getSelection().selectFileEnd(); }
-});
-canon.addCommand({
+ bindKey: bindKey("Ctrl-Shift-End", "Command-Shift-Down"),
+ exec: function(editor) { editor.getSelection().selectFileEnd(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "gotoend",
- bindKey: bindKey("Ctrl-End|Ctrl-Down", "Command-End|Command-Down"),
- exec: function(env, args, request) { env.editor.navigateFileEnd(); }
-});
-canon.addCommand({
+ bindKey: bindKey("Ctrl-End", "Command-End|Command-Down"),
+ exec: function(editor) { editor.navigateFileEnd(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "selectdown",
bindKey: bindKey("Shift-Down", "Shift-Down"),
- exec: function(env, args, request) { env.editor.getSelection().selectDown(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.getSelection().selectDown(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "golinedown",
bindKey: bindKey("Down", "Down|Ctrl-N"),
- exec: function(env, args, request) { env.editor.navigateDown(args.times); }
-});
-canon.addCommand({
+ exec: function(editor, args) { editor.navigateDown(args.times); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "selectwordleft",
bindKey: bindKey("Ctrl-Shift-Left", "Option-Shift-Left"),
- exec: function(env, args, request) { env.editor.getSelection().selectWordLeft(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.getSelection().selectWordLeft(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "gotowordleft",
bindKey: bindKey("Ctrl-Left", "Option-Left"),
- exec: function(env, args, request) { env.editor.navigateWordLeft(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.navigateWordLeft(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "selecttolinestart",
bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left"),
- exec: function(env, args, request) { env.editor.getSelection().selectLineStart(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.getSelection().selectLineStart(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "gotolinestart",
bindKey: bindKey("Alt-Left|Home", "Command-Left|Home|Ctrl-A"),
- exec: function(env, args, request) { env.editor.navigateLineStart(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.navigateLineStart(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "selectleft",
bindKey: bindKey("Shift-Left", "Shift-Left"),
- exec: function(env, args, request) { env.editor.getSelection().selectLeft(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.getSelection().selectLeft(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "gotoleft",
bindKey: bindKey("Left", "Left|Ctrl-B"),
- exec: function(env, args, request) { env.editor.navigateLeft(args.times); }
-});
-canon.addCommand({
+ exec: function(editor, args) { editor.navigateLeft(args.times); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "selectwordright",
bindKey: bindKey("Ctrl-Shift-Right", "Option-Shift-Right"),
- exec: function(env, args, request) { env.editor.getSelection().selectWordRight(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.getSelection().selectWordRight(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "gotowordright",
bindKey: bindKey("Ctrl-Right", "Option-Right"),
- exec: function(env, args, request) { env.editor.navigateWordRight(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.navigateWordRight(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "selecttolineend",
bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right"),
- exec: function(env, args, request) { env.editor.getSelection().selectLineEnd(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.getSelection().selectLineEnd(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "gotolineend",
bindKey: bindKey("Alt-Right|End", "Command-Right|End|Ctrl-E"),
- exec: function(env, args, request) { env.editor.navigateLineEnd(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.navigateLineEnd(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "selectright",
bindKey: bindKey("Shift-Right", "Shift-Right"),
- exec: function(env, args, request) { env.editor.getSelection().selectRight(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.getSelection().selectRight(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "gotoright",
bindKey: bindKey("Right", "Right|Ctrl-F"),
- exec: function(env, args, request) { env.editor.navigateRight(args.times); }
-});
-canon.addCommand({
+ exec: function(editor, args) { editor.navigateRight(args.times); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "selectpagedown",
- bindKey: bindKey("Shift-PageDown", "Shift-PageDown"),
- exec: function(env, args, request) { env.editor.selectPageDown(); }
-});
-canon.addCommand({
+ bindKey: "Shift-PageDown",
+ exec: function(editor) { editor.selectPageDown(); },
+ readOnly: true
+}, {
name: "pagedown",
- bindKey: bindKey(null, "PageDown"),
- exec: function(env, args, request) { env.editor.scrollPageDown(); }
-});
-canon.addCommand({
+ bindKey: bindKey(null, "Option-PageDown"),
+ exec: function(editor) { editor.scrollPageDown(); },
+ readOnly: true
+}, {
name: "gotopagedown",
- bindKey: bindKey("PageDown", "Option-PageDown|Ctrl-V"),
- exec: function(env, args, request) { env.editor.gotoPageDown(); }
-});
-canon.addCommand({
+ bindKey: bindKey("PageDown", "PageDown|Ctrl-V"),
+ exec: function(editor) { editor.gotoPageDown(); },
+ readOnly: true
+}, {
name: "selectpageup",
- bindKey: bindKey("Shift-PageUp", "Shift-PageUp"),
- exec: function(env, args, request) { env.editor.selectPageUp(); }
-});
-canon.addCommand({
+ bindKey: "Shift-PageUp",
+ exec: function(editor) { editor.selectPageUp(); },
+ readOnly: true
+}, {
name: "pageup",
- bindKey: bindKey(null, "PageUp"),
- exec: function(env, args, request) { env.editor.scrollPageUp(); }
-});
-canon.addCommand({
+ bindKey: bindKey(null, "Option-PageUp"),
+ exec: function(editor) { editor.scrollPageUp(); },
+ readOnly: true
+}, {
name: "gotopageup",
- bindKey: bindKey("PageUp", "Option-PageUp"),
- exec: function(env, args, request) { env.editor.gotoPageUp(); }
-});
-canon.addCommand({
+ bindKey: "PageUp",
+ exec: function(editor) { editor.gotoPageUp(); },
+ readOnly: true
+}, {
+ name: "scrollup",
+ bindKey: bindKey("Ctrl-Up", null),
+ exec: function(e) { e.renderer.scrollBy(0, -2 * e.renderer.layerConfig.lineHeight); },
+ readOnly: true
+}, {
+ name: "scrolldown",
+ bindKey: bindKey("Ctrl-Down", null),
+ exec: function(e) { e.renderer.scrollBy(0, 2 * e.renderer.layerConfig.lineHeight); },
+ readOnly: true
+}, {
name: "selectlinestart",
- bindKey: bindKey("Shift-Home", "Shift-Home"),
- exec: function(env, args, request) { env.editor.getSelection().selectLineStart(); }
-});
-canon.addCommand({
+ bindKey: "Shift-Home",
+ exec: function(editor) { editor.getSelection().selectLineStart(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
name: "selectlineend",
- bindKey: bindKey("Shift-End", "Shift-End"),
- exec: function(env, args, request) { env.editor.getSelection().selectLineEnd(); }
-});
-canon.addCommand({
+ bindKey: "Shift-End",
+ exec: function(editor) { editor.getSelection().selectLineEnd(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
+ name: "togglerecording",
+ bindKey: bindKey("Ctrl-Alt-E", "Command-Option-E"),
+ exec: function(editor) { editor.commands.toggleRecording(editor); },
+ readOnly: true
+}, {
+ name: "replaymacro",
+ bindKey: bindKey("Ctrl-Shift-E", "Command-Shift-E"),
+ exec: function(editor) { editor.commands.replay(editor); },
+ readOnly: true
+}, {
+ name: "jumptomatching",
+ bindKey: bindKey("Ctrl-P", "Ctrl-Shift-P"),
+ exec: function(editor) { editor.jumpToMatching(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
+ name: "selecttomatching",
+ bindKey: bindKey("Ctrl-Shift-P", null),
+ exec: function(editor) { editor.jumpToMatching(true); },
+ readOnly: true
+},
+
+// commands disabled in readOnly mode
+{
+ name: "cut",
+ exec: function(editor) {
+ var range = editor.getSelectionRange();
+ editor._emit("cut", range);
+
+ if (!editor.selection.isEmpty()) {
+ editor.session.remove(range);
+ editor.clearSelection();
+ }
+ },
+ multiSelectAction: "forEach"
+}, {
+ name: "removeline",
+ bindKey: bindKey("Ctrl-D", "Command-D"),
+ exec: function(editor) { editor.removeLines(); },
+ multiSelectAction: "forEach"
+}, {
+ name: "duplicateSelection",
+ bindKey: bindKey("Ctrl-Shift-D", "Command-Shift-D"),
+ exec: function(editor) { editor.duplicateSelection(); },
+ multiSelectAction: "forEach"
+}, {
+ name: "sortlines",
+ bindKey: bindKey("Ctrl-Alt-S", "Command-Alt-S"),
+ exec: function(editor) { editor.sortLines(); },
+ multiSelectAction: "forEach"
+}, {
+ name: "togglecomment",
+ bindKey: bindKey("Ctrl-/", "Command-/"),
+ exec: function(editor) { editor.toggleCommentLines(); },
+ multiSelectAction: "forEach"
+}, {
+ name: "modifyNumberUp",
+ bindKey: bindKey("Ctrl-Shift-Up", "Alt-Shift-Up"),
+ exec: function(editor) { editor.modifyNumber(1); },
+ multiSelectAction: "forEach"
+}, {
+ name: "modifyNumberDown",
+ bindKey: bindKey("Ctrl-Shift-Down", "Alt-Shift-Down"),
+ exec: function(editor) { editor.modifyNumber(-1); },
+ multiSelectAction: "forEach"
+}, {
+ name: "replace",
+ bindKey: bindKey("Ctrl-R", "Command-Option-F"),
+ exec: function(editor) {
+ var needle = prompt("Find:", editor.getCopyText());
+ if (!needle)
+ return;
+ var replacement = prompt("Replacement:");
+ if (!replacement)
+ return;
+ editor.replace(replacement, {needle: needle});
+ }
+}, {
+ name: "replaceall",
+ bindKey: bindKey("Ctrl-Shift-R", "Command-Shift-Option-F"),
+ exec: function(editor) {
+ var needle = prompt("Find:");
+ if (!needle)
+ return;
+ var replacement = prompt("Replacement:");
+ if (!replacement)
+ return;
+ editor.replaceAll(replacement, {needle: needle});
+ }
+}, {
+ name: "undo",
+ bindKey: bindKey("Ctrl-Z", "Command-Z"),
+ exec: function(editor) { editor.undo(); }
+}, {
+ name: "redo",
+ bindKey: bindKey("Ctrl-Shift-Z|Ctrl-Y", "Command-Shift-Z|Command-Y"),
+ exec: function(editor) { editor.redo(); }
+}, {
+ name: "copylinesup",
+ bindKey: bindKey("Alt-Shift-Up", "Command-Option-Up"),
+ exec: function(editor) { editor.copyLinesUp(); }
+}, {
+ name: "movelinesup",
+ bindKey: bindKey("Alt-Up", "Option-Up"),
+ exec: function(editor) { editor.moveLinesUp(); }
+}, {
+ name: "copylinesdown",
+ bindKey: bindKey("Alt-Shift-Down", "Command-Option-Down"),
+ exec: function(editor) { editor.copyLinesDown(); }
+}, {
+ name: "movelinesdown",
+ bindKey: bindKey("Alt-Down", "Option-Down"),
+ exec: function(editor) { editor.moveLinesDown(); }
+}, {
name: "del",
bindKey: bindKey("Delete", "Delete|Ctrl-D"),
- exec: function(env, args, request) { env.editor.remove("right"); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.remove("right"); },
+ multiSelectAction: "forEach"
+}, {
name: "backspace",
bindKey: bindKey(
- "Ctrl-Backspace|Command-Backspace|Option-Backspace|Shift-Backspace|Backspace",
+ "Command-Backspace|Option-Backspace|Shift-Backspace|Backspace",
"Ctrl-Backspace|Command-Backspace|Shift-Backspace|Backspace|Ctrl-H"
),
- exec: function(env, args, request) { env.editor.remove("left"); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.remove("left"); },
+ multiSelectAction: "forEach"
+}, {
name: "removetolinestart",
- bindKey: bindKey("Alt-Backspace", "Option-Backspace"),
- exec: function(env, args, request) { env.editor.removeToLineStart(); }
-});
-canon.addCommand({
+ bindKey: bindKey("Alt-Backspace", "Command-Backspace"),
+ exec: function(editor) { editor.removeToLineStart(); },
+ multiSelectAction: "forEach"
+}, {
name: "removetolineend",
bindKey: bindKey("Alt-Delete", "Ctrl-K"),
- exec: function(env, args, request) { env.editor.removeToLineEnd(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.removeToLineEnd(); },
+ multiSelectAction: "forEach"
+}, {
name: "removewordleft",
bindKey: bindKey("Ctrl-Backspace", "Alt-Backspace|Ctrl-Alt-Backspace"),
- exec: function(env, args, request) { env.editor.removeWordLeft(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.removeWordLeft(); },
+ multiSelectAction: "forEach"
+}, {
name: "removewordright",
bindKey: bindKey("Ctrl-Delete", "Alt-Delete"),
- exec: function(env, args, request) { env.editor.removeWordRight(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.removeWordRight(); },
+ multiSelectAction: "forEach"
+}, {
name: "outdent",
bindKey: bindKey("Shift-Tab", "Shift-Tab"),
- exec: function(env, args, request) { env.editor.blockOutdent(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.blockOutdent(); },
+ multiSelectAction: "forEach"
+}, {
name: "indent",
bindKey: bindKey("Tab", "Tab"),
- exec: function(env, args, request) { env.editor.indent(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.indent(); },
+ multiSelectAction: "forEach"
+}, {
+ name: "insertstring",
+ exec: function(editor, str) { editor.insert(str); },
+ multiSelectAction: "forEach"
+}, {
name: "inserttext",
- exec: function(env, args, request) {
- env.editor.insert(lang.stringRepeat(args.text || "", args.times || 1));
- }
-});
-canon.addCommand({
- name: "centerselection",
- bindKey: bindKey(null, "Ctrl-L"),
- exec: function(env, args, request) { env.editor.centerSelection(); }
-});
-canon.addCommand({
+ exec: function(editor, args) {
+ editor.insert(lang.stringRepeat(args.text || "", args.times || 1));
+ },
+ multiSelectAction: "forEach"
+}, {
name: "splitline",
bindKey: bindKey(null, "Ctrl-O"),
- exec: function(env, args, request) { env.editor.splitLine(); }
-});
-canon.addCommand({
+ exec: function(editor) { editor.splitLine(); },
+ multiSelectAction: "forEach"
+}, {
name: "transposeletters",
bindKey: bindKey("Ctrl-T", "Ctrl-T"),
- exec: function(env, args, request) { env.editor.transposeLetters(); }
-});
-
-canon.addCommand({
- name: "fold",
- bindKey: bindKey("Alt-L", "Alt-L"),
- exec: function(env) {
- env.editor.session.toggleFold(false);
- }
-});
-canon.addCommand({
- name: "unfold",
- bindKey: bindKey("Alt-Shift-L", "Alt-Shift-L"),
- exec: function(env) {
- env.editor.session.toggleFold(true);
- }
-});
-canon.addCommand({
- name: "foldall",
- bindKey: bindKey("Alt-Shift-0", "Alt-Shift-0"),
- exec: function(env) {
- env.editor.session.foldAll();
- }
-});
-canon.addCommand({
- name: "unfoldall",
- bindKey: bindKey("Alt-Shift-0", "Alt-Shift-0"),
- exec: function(env) {
- env.editor.session.unFoldAll();
- }
-});
+ exec: function(editor) { editor.transposeLetters(); },
+ multiSelectAction: function(editor) {editor.transposeSelections(1); }
+}, {
+ name: "touppercase",
+ bindKey: bindKey("Ctrl-U", "Ctrl-U"),
+ exec: function(editor) { editor.toUpperCase(); },
+ multiSelectAction: "forEach"
+}, {
+ name: "tolowercase",
+ bindKey: bindKey("Ctrl-Shift-U", "Ctrl-Shift-U"),
+ exec: function(editor) { editor.toLowerCase(); },
+ multiSelectAction: "forEach"
+}];
});
View
97 src/ace/commands/multi_select_commands.js
@@ -0,0 +1,97 @@
+/* ***** 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 ***** */
+
+define(function(require, exports, module) {
+
+// commands to enter multiselect mode
+exports.defaultCommands = [{
+ name: "addCursorAbove",
+ exec: function(editor) { editor.selectMoreLines(-1); },
+ bindKey: {win: "Ctrl-Alt-Up", mac: "Ctrl-Alt-Up"},
+ readonly: true
+}, {
+ name: "addCursorBelow",
+ exec: function(editor) { editor.selectMoreLines(1); },
+ bindKey: {win: "Ctrl-Alt-Down", mac: "Ctrl-Alt-Down"},
+ readonly: true
+}, {
+ name: "addCursorAboveSkipCurrent",
+ exec: function(editor) { editor.selectMoreLines(-1, true); },
+ bindKey: {win: "Ctrl-Alt-Shift-Up", mac: "Ctrl-Alt-Shift-Up"},
+ readonly: true
+}, {
+ name: "addCursorBelowSkipCurrent",