");
function renderOption(builder, option, obj, cValue) {
- builder.push("");
}
for (var option in options) {
@@ -491,7 +491,7 @@ function setupSettingPanel(settingDiv, settingOpener, api, options) {
var option = select.title;
var value = select.value;
api.setOption(option, value);
- }
+ };
})();
selects[i].onchange = onChange;
}
@@ -501,12 +501,12 @@ function setupSettingPanel(settingDiv, settingOpener, api, options) {
button.value = "Hide";
button.onclick = function() {
api.setDisplaySettings(false);
- }
+ };
settingDiv.appendChild(button);
settingOpener.onclick = function() {
api.setDisplaySettings(true);
- }
+ };
}
// Default startup options.
@@ -518,8 +518,8 @@ window.__ace_shadowed__.options = {
softWrap: "off",
showPrintMargin: "false",
useSoftTabs: "true"
-}
+};
});
-})()
+})();
diff --git a/build_support/mini_require.js b/build_support/mini_require.js
index 02955bc6..a2caa55f 100644
--- a/build_support/mini_require.js
+++ b/build_support/mini_require.js
@@ -40,14 +40,14 @@
* @param module a name for the payload
* @param payload a function to call with (require, exports, module) params
*/
-
+
(function() {
-
+
if (window.require) {
require.packaged = true;
return;
}
-
+
var _define = function(module, deps, payload) {
if (typeof module !== 'string') {
if (_define.original)
@@ -64,12 +64,12 @@ var _define = function(module, deps, payload) {
if (!define.modules)
define.modules = {};
-
+
define.modules[module] = payload;
};
if (window.define)
_define.original = window.define;
-
+
window.define = _define;
@@ -93,11 +93,11 @@ var _require = function(module, callback) {
var payload = lookup(module);
if (!payload && _require.original)
return _require.original.apply(window, arguments);
-
+
if (callback) {
callback();
}
-
+
return payload;
}
else {
@@ -108,7 +108,7 @@ var _require = function(module, callback) {
if (window.require)
_require.original = window.require;
-
+
window.require = _require;
require.packaged = true;
@@ -134,4 +134,4 @@ var lookup = function(moduleName) {
return module;
};
-})();
\ No newline at end of file
+})();
diff --git a/build_support/mini_require_textarea.js b/build_support/mini_require_textarea.js
index 42b1d2bb..643aa953 100644
--- a/build_support/mini_require_textarea.js
+++ b/build_support/mini_require_textarea.js
@@ -92,7 +92,7 @@ var _require = function(module, callback) {
return payload;
};
-}
+};
_require.packaged = true;
_require.noWorker = true;
diff --git a/demo/boot.js b/demo/boot.js
index 1fddaf72..8da8d05b 100644
--- a/demo/boot.js
+++ b/demo/boot.js
@@ -39,21 +39,29 @@ require({
paths: {
demo: "../demo",
ace: "../lib/ace",
- cockpit: "../support/cockpit/lib/cockpit",
- pilot: "../support/pilot/lib/pilot"
+ gcli: "../support/cockpit/lib/gcli",
+ pilot: "../support/cockpit/support/pilot/lib/pilot"
}
});
-var deps = [ "pilot/fixoldbrowsers", "pilot/plugin_manager", "pilot/settings",
- "pilot/environment", "demo/demo" ];
+var deps = [
+ "pilot/fixoldbrowsers",
+ "ace/plugin_manager",
+ "ace/environment",
+ "demo/demo"
+];
-var plugins = [ "pilot/index", "cockpit/index", "ace/defaults" ];
require(deps, function() {
- var catalog = require("pilot/plugin_manager").catalog;
+ var catalog = require("ace/plugin_manager").catalog;
+
+ var plugins = [ "gcli/index", "ace/index" ];
catalog.registerPlugins(plugins).then(function() {
- var env = require("pilot/environment").create();
+ var env = require("ace/environment").create();
catalog.startupPlugins({ env: env }).then(function() {
require("demo/demo").launch(env);
+
+ var gcli = require("gcli/index");
+ gcli.createView({ env: env });
});
});
-});
\ No newline at end of file
+});
diff --git a/demo/demo.js b/demo/demo.js
index 9c64de10..0189d10c 100644
--- a/demo/demo.js
+++ b/demo/demo.js
@@ -36,11 +36,13 @@
*
* ***** END LICENSE BLOCK ***** */
-
define(function(require, exports, module) {
+
+var keybinding = require('ace/keyboard/keybinding');
+
exports.launch = function(env) {
- var canon = require("pilot/canon");
+ var gcli = require("gcli/index");
var event = require("pilot/event");
var Editor = require("ace/editor").Editor;
var Renderer = require("ace/virtual_renderer").VirtualRenderer;
@@ -77,7 +79,7 @@ exports.launch = function(env) {
custom: new HashHandler({
"gotoright": "Tab"
})
- }
+ };
var docs = {};
@@ -88,7 +90,7 @@ exports.launch = function(env) {
}
docs.plain = new EditSession(loreIpsum);
docs.plain.setUseWrapMode(true);
- docs.plain.setWrapLimitRange(80, 80)
+ docs.plain.setWrapLimitRange(80, 80);
docs.plain.setMode(new TextMode());
docs.plain.setUndoManager(new UndoManager());
@@ -393,62 +395,31 @@ exports.launch = function(env) {
*/
// Command to focus the command line from the editor.
- canon.addCommand({
+ gcli.addCommand({
name: "focuscli",
- bindKey: {
- win: "Ctrl-J",
- mac: "Command-J",
- sender: "editor"
- },
exec: function() {
env.cli.cliView.element.focus();
}
});
+ keybinding.bindCommand({ win: "Ctrl-J", mac: "Command-J" }, "focuscli");
// Command to focus the editor line from the command line.
- canon.addCommand({
+ gcli.addCommand({
name: "focuseditor",
- bindKey: {
- win: "Ctrl-J",
- mac: "Command-J",
- sender: "cli"
- },
exec: function() {
env.editor.focus();
}
});
+ keybinding.bindCommand({ win: "Ctrl-J", mac: "Command-J" }, "focuseditor");
// Fake-Save, works from the editor and the command line.
- canon.addCommand({
+ gcli.addCommand({
name: "save",
- bindKey: {
- win: "Ctrl-S",
- mac: "Command-S",
- sender: "editor|cli"
- },
exec: function() {
alert("Fake Save File");
}
});
-
- // Fake-Print with custom lookup-sender-match function.
- canon.addCommand({
- name: "save",
- bindKey: {
- win: "Ctrl-P",
- mac: "Command-P",
- sender: function(env, sender, hashId, keyString) {
- if (sender == "editor") {
- return true;
- } else {
- alert("Sorry, can only print from the editor");
- }
- }
- },
- exec: function() {
- alert("Fake Print File");
- }
- });
+ keybinding.bindCommand({ win: "Ctrl-S", mac: "Command-S" }, "save");
};
});
diff --git a/demo/styles.css b/demo/styles.css
index 3f244f7c..0d9af881 100644
--- a/demo/styles.css
+++ b/demo/styles.css
@@ -26,7 +26,7 @@ body {
width: 100%;
}
-#cockpitInput {
+#gcliInput {
position: absolute;
width: 100%;
bottom: 0;
@@ -36,12 +36,11 @@ body {
font-size: 120%;
}
-#cockpitOutput {
- padding: 10px;
+#gcliOutput {
margin: 0 15px;
border: 1px solid #AAA;
-moz-border-radius-topleft: 10px;
-moz-border-radius-topright: 10px;
border-top-left-radius: 4px; border-top-right-radius: 4px;
background: #DDD; color: #000;
-}
\ No newline at end of file
+}
diff --git a/index.html b/index.html
index c79abe0f..8ca83b2b 100644
--- a/index.html
+++ b/index.html
@@ -450,7 +450,7 @@ bg. Blockquote!
-
+
diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js
index 9b300747..35e5adeb 100644
--- a/lib/ace/commands/default_commands.js
+++ b/lib/ace/commands/default_commands.js
@@ -40,329 +40,423 @@
define(function(require, exports, module) {
+
var lang = require("pilot/lang");
-var canon = require("pilot/canon");
+var gcli = require("gcli/index");
+var keybinding = require('ace/keyboard/keybinding');
-function bindKey(win, mac) {
- return {
- win: win,
- mac: mac,
- sender: "editor"
- };
-}
+/**
+ * TODO: This could be done more concisely and reversibly
+ */
+exports.startup = function() {
+ gcli.addCommand({
+ name: "null",
+ exec: function(env, args) { }
+ });
-canon.addCommand({
- name: "null",
- exec: function(env, args, request) { }
-});
+ gcli.addCommand({
+ name: "selectall",
+ exec: function(env, args) { env.editor.selectAll(); }
+ });
+ keybinding.bindCommand({ win: "Ctrl-A", mac: "Command-A" }, "selectall");
-canon.addCommand({
- 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({
- name: "gotoline",
- bindKey: bindKey("Ctrl-L", "Command-L"),
- exec: function(env, args, request) {
- var line = parseInt(prompt("Enter line number:"));
- if (!isNaN(line)) {
- env.editor.gotoLine(line);
+ gcli.addCommand({
+ name: "removeline",
+ exec: function(env, args) { env.editor.removeLines(); }
+ });
+ keybinding.bindCommand({ win: "Ctrl-D", mac: "Command-D" }, "removeline");
+
+ gcli.addCommand({
+ name: "gotoline",
+ description: "Move the cursor to the given line",
+ params: [
+ { name: "line", type: "number", description: "The line number to jump to" }
+ ],
+ exec: function(env, args) {
+ // TODO: manual params should not be needed
+ if (!args.line) {
+ while (!isNaN(args.line)) {
+ args.line = parseInt(prompt("Enter line number:"));
+ }
+ }
+ env.editor.gotoLine(args.line);
}
- }
-});
-canon.addCommand({
- name: "togglecomment",
- bindKey: bindKey("Ctrl-7", "Command-7"),
- exec: function(env, args, request) { env.editor.toggleCommentLines(); }
-});
-canon.addCommand({
- name: "findnext",
- bindKey: bindKey("Ctrl-K", "Command-G"),
- exec: function(env, args, request) { env.editor.findNext(); }
-});
-canon.addCommand({
- name: "findprevious",
- bindKey: bindKey("Ctrl-Shift-K", "Command-Shift-G"),
- exec: function(env, args, request) { env.editor.findPrevious(); }
-});
-canon.addCommand({
- name: "find",
- bindKey: bindKey("Ctrl-F", "Command-F"),
- exec: function(env, args, request) {
- var needle = prompt("Find:");
- env.editor.find(needle);
- }
-});
-canon.addCommand({
- name: "replace",
- bindKey: bindKey("Ctrl-R", "Command-Option-F"),
- exec: function(env, args, request) {
- var needle = prompt("Find:");
- 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({
- 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({
- name: "selecttostart",
- bindKey: bindKey("Alt-Shift-Up", "Command-Shift-Up"),
- exec: function(env, args, request) { env.editor.getSelection().selectFileStart(); }
-});
-canon.addCommand({
- name: "gotostart",
- bindKey: bindKey("Ctrl-Home|Ctrl-Up", "Command-Home|Command-Up"),
- exec: function(env, args, request) { env.editor.navigateFileStart(); }
-});
-canon.addCommand({
- name: "selectup",
- bindKey: bindKey("Shift-Up", "Shift-Up"),
- exec: function(env, args, request) { env.editor.getSelection().selectUp(); }
-});
-canon.addCommand({
- 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({
- name: "selecttoend",
- bindKey: bindKey("Alt-Shift-Down", "Command-Shift-Down"),
- exec: function(env, args, request) { env.editor.getSelection().selectFileEnd(); }
-});
-canon.addCommand({
- name: "gotoend",
- bindKey: bindKey("Ctrl-End|Ctrl-Down", "Command-End|Command-Down"),
- exec: function(env, args, request) { env.editor.navigateFileEnd(); }
-});
-canon.addCommand({
- name: "selectdown",
- bindKey: bindKey("Shift-Down", "Shift-Down"),
- exec: function(env, args, request) { env.editor.getSelection().selectDown(); }
-});
-canon.addCommand({
- name: "golinedown",
- bindKey: bindKey("Down", "Down|Ctrl-N"),
- exec: function(env, args, request) { env.editor.navigateDown(args.times); }
-});
-canon.addCommand({
- name: "selectwordleft",
- bindKey: bindKey("Ctrl-Shift-Left", "Option-Shift-Left"),
- exec: function(env, args, request) { env.editor.getSelection().selectWordLeft(); }
-});
-canon.addCommand({
- name: "gotowordleft",
- bindKey: bindKey("Ctrl-Left", "Option-Left"),
- exec: function(env, args, request) { env.editor.navigateWordLeft(); }
-});
-canon.addCommand({
- name: "selecttolinestart",
- bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left"),
- exec: function(env, args, request) { env.editor.getSelection().selectLineStart(); }
-});
-canon.addCommand({
- name: "gotolinestart",
- bindKey: bindKey("Alt-Left|Home", "Command-Left|Home|Ctrl-A"),
- exec: function(env, args, request) { env.editor.navigateLineStart(); }
-});
-canon.addCommand({
- name: "selectleft",
- bindKey: bindKey("Shift-Left", "Shift-Left"),
- exec: function(env, args, request) { env.editor.getSelection().selectLeft(); }
-});
-canon.addCommand({
- name: "gotoleft",
- bindKey: bindKey("Left", "Left|Ctrl-B"),
- exec: function(env, args, request) { env.editor.navigateLeft(args.times); }
-});
-canon.addCommand({
- name: "selectwordright",
- bindKey: bindKey("Ctrl-Shift-Right", "Option-Shift-Right"),
- exec: function(env, args, request) { env.editor.getSelection().selectWordRight(); }
-});
-canon.addCommand({
- name: "gotowordright",
- bindKey: bindKey("Ctrl-Right", "Option-Right"),
- exec: function(env, args, request) { env.editor.navigateWordRight(); }
-});
-canon.addCommand({
- name: "selecttolineend",
- bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right"),
- exec: function(env, args, request) { env.editor.getSelection().selectLineEnd(); }
-});
-canon.addCommand({
- name: "gotolineend",
- bindKey: bindKey("Alt-Right|End", "Command-Right|End|Ctrl-E"),
- exec: function(env, args, request) { env.editor.navigateLineEnd(); }
-});
-canon.addCommand({
- name: "selectright",
- bindKey: bindKey("Shift-Right", "Shift-Right"),
- exec: function(env, args, request) { env.editor.getSelection().selectRight(); }
-});
-canon.addCommand({
- name: "gotoright",
- bindKey: bindKey("Right", "Right|Ctrl-F"),
- exec: function(env, args, request) { env.editor.navigateRight(args.times); }
-});
-canon.addCommand({
- name: "selectpagedown",
- bindKey: bindKey("Shift-PageDown", "Shift-PageDown"),
- exec: function(env, args, request) { env.editor.selectPageDown(); }
-});
-canon.addCommand({
- name: "pagedown",
- bindKey: bindKey(null, "PageDown"),
- exec: function(env, args, request) { env.editor.scrollPageDown(); }
-});
-canon.addCommand({
- name: "gotopagedown",
- bindKey: bindKey("PageDown", "Option-PageDown|Ctrl-V"),
- exec: function(env, args, request) { env.editor.gotoPageDown(); }
-});
-canon.addCommand({
- name: "selectpageup",
- bindKey: bindKey("Shift-PageUp", "Shift-PageUp"),
- exec: function(env, args, request) { env.editor.selectPageUp(); }
-});
-canon.addCommand({
- name: "pageup",
- bindKey: bindKey(null, "PageUp"),
- exec: function(env, args, request) { env.editor.scrollPageUp(); }
-});
-canon.addCommand({
- name: "gotopageup",
- bindKey: bindKey("PageUp", "Option-PageUp"),
- exec: function(env, args, request) { env.editor.gotoPageUp(); }
-});
-canon.addCommand({
- name: "selectlinestart",
- bindKey: bindKey("Shift-Home", "Shift-Home"),
- exec: function(env, args, request) { env.editor.getSelection().selectLineStart(); }
-});
-canon.addCommand({
- name: "selectlineend",
- bindKey: bindKey("Shift-End", "Shift-End"),
- exec: function(env, args, request) { env.editor.getSelection().selectLineEnd(); }
-});
-canon.addCommand({
- name: "del",
- bindKey: bindKey("Delete", "Delete|Ctrl-D"),
- exec: function(env, args, request) { env.editor.removeRight(); }
-});
-canon.addCommand({
- name: "backspace",
- bindKey: bindKey(
- "Ctrl-Backspace|Command-Backspace|Option-Backspace|Shift-Backspace|Backspace",
- "Ctrl-Backspace|Command-Backspace|Shift-Backspace|Backspace|Ctrl-H"
- ),
- exec: function(env, args, request) { env.editor.removeLeft(); }
-});
-canon.addCommand({
- name: "removetolinestart",
- bindKey: bindKey(null, "Option-Backspace"),
- exec: function(env, args, request) { env.editor.removeToLineStart(); }
-});
-canon.addCommand({
- name: "removetolineend",
- bindKey: bindKey(null, "Ctrl-K"),
- exec: function(env, args, request) { env.editor.removeToLineEnd(); }
-});
-canon.addCommand({
- name: "removewordleft",
- bindKey: bindKey(null, "Alt-Backspace|Ctrl-Alt-Backspace"),
- exec: function(env, args, request) { env.editor.removeWordLeft(); }
-});
-canon.addCommand({
- name: "removewordright",
- bindKey: bindKey(null, "Alt-Delete"),
- exec: function(env, args, request) { env.editor.removeWordRight(); }
-});
-canon.addCommand({
- name: "outdent",
- bindKey: bindKey("Shift-Tab", "Shift-Tab"),
- exec: function(env, args, request) { env.editor.blockOutdent(); }
-});
-canon.addCommand({
- name: "indent",
- bindKey: bindKey("Tab", "Tab"),
- exec: function(env, args, request) { env.editor.indent(); }
-});
-canon.addCommand({
- 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({
- name: "splitline",
- bindKey: bindKey(null, "Ctrl-O"),
- exec: function(env, args, request) { env.editor.splitLine(); }
-});
-canon.addCommand({
- name: "transposeletters",
- bindKey: bindKey("Ctrl-T", "Ctrl-T"),
- exec: function(env, args, request) { env.editor.transposeLetters(); }
-});
+ });
+ keybinding.bindCommand({ win: "Ctrl-L", mac: "Command-L" }, "gotoline");
-});
\ No newline at end of file
+ gcli.addCommand({
+ name: "togglecomment",
+ exec: function(env, args) { env.editor.toggleCommentLines(); }
+ });
+ keybinding.bindCommand({ win: "Ctrl-7", mac: "Command-7" }, "togglecomment");
+
+ gcli.addCommand({
+ name: "findnext",
+ exec: function(env, args) { env.editor.findNext(); }
+ });
+ keybinding.bindCommand({ win: "Ctrl-K", mac: "Command-G" }, "findnext");
+
+ gcli.addCommand({
+ name: "findprevious",
+ exec: function(env, args) { env.editor.findPrevious(); }
+ });
+ keybinding.bindCommand({ win: "Ctrl-Shift-K", mac: "Command-Shift-G" }, "findprevious");
+
+ gcli.addCommand({
+ name: "find",
+ description: "Search for the next instance of a string",
+ params: [
+ { name: "findWhat", type: "string", description: "The text to search for" }
+ ],
+ exec: function(env, args) {
+ // TODO: manual params should not be needed
+ if (!args.findWhat) {
+ args.findWhat = prompt("Find:");
+ }
+ env.editor.find(args.findWhat);
+ }
+ });
+ keybinding.bindCommand({ win: "Ctrl-F", mac: "Command-F" }, "find");
+
+ gcli.addCommand({
+ name: "replace",
+ description: "Replace the next instance of a string with a given replacement",
+ params: [
+ { name: "findWhat", type: "string", description: "The text to search for" },
+ { name: "replacement", type: "string", description: "The replacement text" }
+ ],
+ exec: function(env, args) {
+ // TODO: manual params should not be needed
+ if (!args.findWhat) {
+ args.findWhat = prompt("Find:");
+ if (!args.findWhat) {
+ return;
+ }
+ args.replacement = prompt("Replacement:");
+ if (!args.replacement) {
+ return;
+ }
+ }
+ env.editor.replace(args.replacement, {needle: args.findWhat});
+ }
+ });
+ keybinding.bindCommand({ win: "Ctrl-R", mac: "Command-Option-F" }, "replace");
+
+ gcli.addCommand({
+ name: "replaceall",
+ description: "Replace all instances of a string with a given replacement",
+ params: [
+ { name: "findWhat", type: "string", description: "The text to search for" },
+ { name: "replacement", type: "string", description: "The replacement text" }
+ ],
+ exec: function(env, args) {
+ // TODO: manual params should not be needed
+ if (!args.findWhat) {
+ args.findWhat = prompt("Find:");
+ if (!args.findWhat) {
+ return;
+ }
+ args.replacement = prompt("Replacement:");
+ if (!args.replacement) {
+ return;
+ }
+ }
+ env.editor.replaceAll(args.replacement, {needle: args.findWhat});
+ }
+ });
+ keybinding.bindCommand({ win: "Ctrl-Shift-R", mac: "Command-Shift-Option-F" }, "replaceall");
+
+ gcli.addCommand({
+ name: "undo",
+ exec: function(env, args) { env.editor.undo(); }
+ });
+ keybinding.bindCommand({ win: "Ctrl-Z", mac: "Command-Z" }, "undo");
+
+ gcli.addCommand({
+ name: "redo",
+ exec: function(env, args) { env.editor.redo(); }
+ });
+ keybinding.bindCommand({ win: "Ctrl-Shift-Z|Ctrl-Y", mac: "Command-Shift-Z|Command-Y" }, "redo");
+
+ gcli.addCommand({
+ name: "overwrite",
+ exec: function(env, args) { env.editor.toggleOverwrite(); }
+ });
+ keybinding.bindCommand({ win: "Insert", mac: "Insert" }, "overwrite");
+
+ gcli.addCommand({
+ name: "copylinesup",
+ exec: function(env, args) { env.editor.copyLinesUp(); }
+ });
+ keybinding.bindCommand({ win: "Ctrl-Alt-Up", mac: "Command-Option-Up" }, "copylinesup");
+
+ gcli.addCommand({
+ name: "movelinesup",
+ exec: function(env, args) { env.editor.moveLinesUp(); }
+ });
+ keybinding.bindCommand({ win: "Alt-Up", mac: "Option-Up" }, "movelinesup");
+
+ gcli.addCommand({
+ name: "selecttostart",
+ exec: function(env, args) { env.editor.getSelection().selectFileStart(); }
+ });
+ keybinding.bindCommand({ win: "Alt-Shift-Up", mac: "Command-Shift-Up" }, "selecttostart");
+
+ gcli.addCommand({
+ name: "gotostart",
+ exec: function(env, args) { env.editor.navigateFileStart(); }
+ });
+ keybinding.bindCommand({ win: "Ctrl-Home|Ctrl-Up", mac: "Command-Home|Command-Up" }, "gotostart");
+
+ gcli.addCommand({
+ name: "selectup",
+ exec: function(env, args) { env.editor.getSelection().selectUp(); }
+ });
+ keybinding.bindCommand({ win: "Shift-Up", mac: "Shift-Up" }, "selectup");
+
+ gcli.addCommand({
+ name: "golineup",
+ exec: function(env, args) { env.editor.navigateUp(args.times); }
+ });
+ keybinding.bindCommand({ win: "Up", mac: "Up|Ctrl-P" }, "golineup");
+
+ gcli.addCommand({
+ name: "copylinesdown",
+ exec: function(env, args) { env.editor.copyLinesDown(); }
+ });
+ keybinding.bindCommand({ win: "Ctrl-Alt-Down", mac: "Command-Option-Down" }, "copylinesdown");
+
+ gcli.addCommand({
+ name: "movelinesdown",
+ exec: function(env, args) { env.editor.moveLinesDown(); }
+ });
+ keybinding.bindCommand({ win: "Alt-Down", mac: "Option-Down" }, "movelinesdown");
+
+ gcli.addCommand({
+ name: "selecttoend",
+ exec: function(env, args) { env.editor.getSelection().selectFileEnd(); }
+ });
+ keybinding.bindCommand({ win: "Alt-Shift-Down", mac: "Command-Shift-Down" }, "selecttoend");
+
+ gcli.addCommand({
+ name: "gotoend",
+ exec: function(env, args) { env.editor.navigateFileEnd(); }
+ });
+ keybinding.bindCommand({ win: "Ctrl-End|Ctrl-Down", mac: "Command-End|Command-Down" }, "gotoend");
+
+ gcli.addCommand({
+ name: "selectdown",
+ exec: function(env, args) { env.editor.getSelection().selectDown(); }
+ });
+ keybinding.bindCommand({ win: "Shift-Down", mac: "Shift-Down" }, "selectdown");
+
+ gcli.addCommand({
+ name: "golinedown",
+ exec: function(env, args) { env.editor.navigateDown(args.times); }
+ });
+ keybinding.bindCommand({ win: "Down", mac: "Down|Ctrl-N" }, "golinedown");
+
+ gcli.addCommand({
+ name: "selectwordleft",
+ exec: function(env, args) { env.editor.getSelection().selectWordLeft(); }
+ });
+ keybinding.bindCommand({ win: "Ctrl-Shift-Left", mac: "Option-Shift-Left" }, "selectwordleft");
+
+ gcli.addCommand({
+ name: "gotowordleft",
+ exec: function(env, args) { env.editor.navigateWordLeft(); }
+ });
+ keybinding.bindCommand({ win: "Ctrl-Left", mac: "Option-Left" }, "gotowordleft");
+
+ gcli.addCommand({
+ name: "selecttolinestart",
+ exec: function(env, args) { env.editor.getSelection().selectLineStart(); }
+ });
+ keybinding.bindCommand({ win: "Alt-Shift-Left", mac: "Command-Shift-Left" }, "selecttolinestart");
+
+ gcli.addCommand({
+ name: "gotolinestart",
+ exec: function(env, args) { env.editor.navigateLineStart(); }
+ });
+ keybinding.bindCommand({ win: "Alt-Left|Home", mac: "Command-Left|Home|Ctrl-A" }, "");
+
+ gcli.addCommand({
+ name: "selectleft",
+ exec: function(env, args) { env.editor.getSelection().selectLeft(); }
+ });
+ keybinding.bindCommand({ win: "Shift-Left", mac: "Shift-Left" }, "gotolinestart");
+
+ gcli.addCommand({
+ name: "gotoleft",
+ exec: function(env, args) { env.editor.navigateLeft(args.times); }
+ });
+ keybinding.bindCommand({ win: "Left", mac: "Left|Ctrl-B" }, "gotoleft");
+
+ gcli.addCommand({
+ name: "selectwordright",
+ exec: function(env, args) { env.editor.getSelection().selectWordRight(); }
+ });
+ keybinding.bindCommand({ win: "Ctrl-Shift-Right", mac: "Option-Shift-Right" }, "selectwordright");
+
+ gcli.addCommand({
+ name: "gotowordright",
+ exec: function(env, args) { env.editor.navigateWordRight(); }
+ });
+ keybinding.bindCommand({ win: "Ctrl-Right", mac: "Option-Right" }, "");
+
+ gcli.addCommand({
+ name: "selecttolineend",
+ exec: function(env, args) { env.editor.getSelection().selectLineEnd(); }
+ });
+ keybinding.bindCommand({ win: "Alt-Shift-Right", mac: "Command-Shift-Right" }, "gotowordright");
+
+ gcli.addCommand({
+ name: "gotolineend",
+ exec: function(env, args) { env.editor.navigateLineEnd(); }
+ });
+ keybinding.bindCommand({ win: "Alt-Right|End", mac: "Command-Right|End|Ctrl-E" }, "gotolineend");
+
+ gcli.addCommand({
+ name: "selectright",
+ exec: function(env, args) { env.editor.getSelection().selectRight(); }
+ });
+ keybinding.bindCommand({ win: "Shift-Right", mac: "Shift-Right" }, "selectright");
+
+ gcli.addCommand({
+ name: "gotoright",
+ exec: function(env, args) { env.editor.navigateRight(args.times); }
+ });
+ keybinding.bindCommand({ win: "Right", mac: "Right|Ctrl-F" }, "gotoright");
+
+ gcli.addCommand({
+ name: "selectpagedown",
+ exec: function(env, args) { env.editor.selectPageDown(); }
+ });
+ keybinding.bindCommand({ win: "Shift-PageDown", mac: "Shift-PageDown" }, "selectpagedown");
+
+ gcli.addCommand({
+ name: "pagedown",
+ exec: function(env, args) { env.editor.scrollPageDown(); }
+ });
+ keybinding.bindCommand({ win: null, mac: "PageDown" }, "pagedown");
+
+ gcli.addCommand({
+ name: "gotopagedown",
+ exec: function(env, args) { env.editor.gotoPageDown(); }
+ });
+ keybinding.bindCommand({ win: "PageDown", mac: "Option-PageDown|Ctrl-V" }, "gotopagedown");
+
+ gcli.addCommand({
+ name: "selectpageup",
+ exec: function(env, args) { env.editor.selectPageUp(); }
+ });
+ keybinding.bindCommand({ win: "Shift-PageUp", mac: "Shift-PageUp" }, "selectpageup");
+
+ gcli.addCommand({
+ name: "pageup",
+ exec: function(env, args) { env.editor.scrollPageUp(); }
+ });
+ keybinding.bindCommand({ win: null, mac: "PageUp" }, "pageup");
+
+ gcli.addCommand({
+ name: "gotopageup",
+ exec: function(env, args) { env.editor.gotoPageUp(); }
+ });
+ keybinding.bindCommand({ win: "PageUp", mac: "Option-PageUp" }, "gotopageup");
+
+ gcli.addCommand({
+ name: "selectlinestart",
+ exec: function(env, args) { env.editor.getSelection().selectLineStart(); }
+ });
+ keybinding.bindCommand({ win: "Shift-Home", mac: "Shift-Home" }, "selectlinestart");
+
+ gcli.addCommand({
+ name: "selectlineend",
+ exec: function(env, args) { env.editor.getSelection().selectLineEnd(); }
+ });
+ keybinding.bindCommand({ win: "Shift-End", mac: "Shift-End" }, "selectlineend");
+
+ gcli.addCommand({
+ name: "del",
+ exec: function(env, args) { env.editor.removeRight(); }
+ });
+ keybinding.bindCommand({ win: "Delete", mac: "Delete|Ctrl-D" }, "del");
+
+ gcli.addCommand({
+ name: "backspace",
+ exec: function(env, args) { env.editor.removeLeft(); }
+ });
+ keybinding.bindCommand({
+ win: "Ctrl-Backspace|Command-Backspace|Option-Backspace|Shift-Backspace|Backspace",
+ mac: "Ctrl-Backspace|Command-Backspace|Shift-Backspace|Backspace|Ctrl-H"
+ }, "backspace");
+
+ gcli.addCommand({
+ name: "removetolinestart",
+ exec: function(env, args) { env.editor.removeToLineStart(); }
+ });
+ keybinding.bindCommand({ win: null, mac: "Option-Backspace" }, "removetolinestart");
+
+ gcli.addCommand({
+ name: "removetolineend",
+ exec: function(env, args) { env.editor.removeToLineEnd(); }
+ });
+ keybinding.bindCommand({ win: null, mac: "Ctrl-K" }, "removetolineend");
+
+ gcli.addCommand({
+ name: "removewordleft",
+ exec: function(env, args) { env.editor.removeWordLeft(); }
+ });
+ keybinding.bindCommand({ win: null, mac: "Alt-Backspace|Ctrl-Alt-Backspace" }, "removewordleft");
+
+ gcli.addCommand({
+ name: "removewordright",
+ exec: function(env, args) { env.editor.removeWordRight(); }
+ });
+ keybinding.bindCommand({ win: null, mac: "Alt-Delete" }, "removewordright");
+
+ gcli.addCommand({
+ name: "outdent",
+ exec: function(env, args) { env.editor.blockOutdent(); }
+ });
+ keybinding.bindCommand({ win: "Shift-Tab", mac: "Shift-Tab" }, "outdent");
+
+ gcli.addCommand({
+ name: "indent",
+ exec: function(env, args) { env.editor.indent(); }
+ });
+ keybinding.bindCommand({ win: "Tab", mac: "Tab" }, "indent");
+
+ gcli.addCommand({
+ name: "inserttext",
+ exec: function(env, args) {
+ env.editor.insert(lang.stringRepeat(args.text || "", args.times || 1));
+ }
+ });
+
+ gcli.addCommand({
+ name: "centerselection",
+ exec: function(env, args) { env.editor.centerSelection(); }
+ });
+ keybinding.bindCommand({ win: null, mac: "Ctrl-L" }, "centerselection");
+
+ gcli.addCommand({
+ name: "splitline",
+ exec: function(env, args) { env.editor.splitLine(); }
+ });
+ keybinding.bindCommand({ win: null, mac: "Ctrl-O" }, "splitline");
+
+ gcli.addCommand({
+ name: "transposeletters",
+ exec: function(env, args) { env.editor.transposeLetters(); }
+ });
+ keybinding.bindCommand({ win: "Ctrl-T", mac: "Ctrl-T" }, "transposeletters");
+};
+
+
+exports.shutdown = function() {
+ // TODO: unregister commands
+};
+
+
+});
diff --git a/lib/ace/commands/settings.js b/lib/ace/commands/settings.js
new file mode 100644
index 00000000..58e660b5
--- /dev/null
+++ b/lib/ace/commands/settings.js
@@ -0,0 +1,136 @@
+/* ***** 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 Skywriter.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Skywriter Team (skywriter@mozilla.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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+
+var gcli = require('gcli/index');
+
+var pref = {
+ metadata: {
+ description: 'Commands for managing preferences'
+ },
+
+ showMetadata: {
+ description: 'Show preferences',
+ params: [
+ {
+ name: 'filter',
+ type: 'string',
+ description: 'Regex filter to show only some settings',
+ defaultValue: null
+ }
+ ]
+ },
+ show: function(filter) {
+ var names = gcli.getEnvironment().settings.getSettingNames();
+ // first sort the settingsList based on the name
+ names.sort(function(name1, name2) {
+ return name1.localeCompare(name2);
+ });
+
+ if (filter) {
+ filter = new RegExp(filter);
+ }
+
+ var html = '';
+ names.forEach(function(name) {
+ if (!filter || filter.test(name)) {
+ var setting = gcli.getEnvironment().settings.getSetting(name);
+ var url = 'https://wiki.mozilla.org/Labs/Skywriter/Settings#' +
+ setting.name;
+ html += '' +
+ setting.name +
+ ' = ' +
+ setting.value +
+ ' ';
+ }
+ });
+
+ return html;
+ },
+
+ setMetadata: {
+ description: 'Alter current settings',
+ params: [
+ {
+ name: 'setting',
+ type: 'setting',
+ description: 'The name of the setting to display or alter'
+ },
+ {
+ name: 'value',
+ type: 'settingValue',
+ description: 'The new value for the chosen setting'
+ }
+ ]
+ },
+ set: function(setting, value) {
+ setting.set(value);
+ return 'Setting: ' + setting.name + ' = ' + setting.get();
+ },
+
+ resetMetadata: {
+ description: 'Reset a preference to it\'s default values',
+ params: [
+ {
+ name: 'setting',
+ type: 'setting',
+ description: 'The name of the setting to return to defaults'
+ }
+ ]
+ },
+ reset: function(setting) {
+ setting.reset();
+ return 'Reset ' + setting.name + ' to default: ' + setting.value;
+ }
+};
+
+
+exports.startup = function() {
+ gcli.addCommands(pref, 'pref');
+};
+
+exports.shutdown = function() {
+ gcli.removeCommands(pref, 'pref');
+};
+
+
+});
diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js
index a96e419a..b4066b05 100644
--- a/lib/ace/edit_session.js
+++ b/lib/ace/edit_session.js
@@ -246,14 +246,14 @@ var EditSession = function(text, mode) {
renderer: typeof type == "function" ? type : null,
clazz : clazz,
inFront: !!inFront
- }
+ };
if (inFront) {
this.$frontMarkers[id] = marker;
- this._dispatchEvent("changeFrontMarker")
+ this._dispatchEvent("changeFrontMarker");
} else {
this.$backMarkers[id] = marker;
- this._dispatchEvent("changeBackMarker")
+ this._dispatchEvent("changeBackMarker");
}
return id;
@@ -606,11 +606,11 @@ var EditSession = function(text, mode) {
deltas = deltas.map(function(delta) {
var d = {
range: delta.range
- }
+ };
if (delta.action == "insertText" || delta.action == "insertLines")
- d.action = "removeText"
+ d.action = "removeText";
else
- d.action = "insertText"
+ d.action = "insertText";
return d;
}).reverse();
@@ -627,7 +627,7 @@ var EditSession = function(text, mode) {
isInsert: isInsert,
start: isInsert ? delta.range.start : delta.range.end,
end: isInsert ? delta.range.end : delta.range.start
- })
+ });
}
else {
if (isInsert)
@@ -958,7 +958,7 @@ var EditSession = function(text, mode) {
}
}
return splits;
- }
+ };
this.$getDisplayTokens = function(str) {
var arr = [];
@@ -986,7 +986,7 @@ var EditSession = function(text, mode) {
}
}
return arr;
- }
+ };
/**
* Calculates the width of the a string on the screen while assuming that
@@ -1005,16 +1005,16 @@ var EditSession = function(text, mode) {
if (c == 9) {
screenColumn += this.getScreenTabSize(screenColumn);
}
- // full width characters
+ // full width characters
else if (isFullWidth(c)) {
screenColumn += 2;
- } else {
- screenColumn += 1;
- }
- }
-
- return screenColumn;
- }
+ } else {
+ screenColumn += 1;
+ }
+ }
+
+ return screenColumn;
+ };
this.getRowHeight = function(config, row) {
var rows;
@@ -1025,7 +1025,7 @@ var EditSession = function(text, mode) {
}
return rows * config.lineHeight;
- }
+ };
this.getScreenLastRowColumn = function(screenRow, returnDocPosition) {
if (!this.$useWrapMode) {
@@ -1059,7 +1059,7 @@ var EditSession = function(text, mode) {
var screenRow = this.documentToScreenRow(docRow, docColumn);
return this.getScreenLastRowColumn(screenRow, true);
- }
+ };
this.getScreenFirstRowColumn = function(screenRow) {
if (!this.$useWrapMode) {
@@ -1138,7 +1138,7 @@ var EditSession = function(text, mode) {
}
if (docRow >= linesCount) {
- docRow = linesCount-1
+ docRow = linesCount-1;
row = wrapData[docRow].length;
}
docColumn = wrapData[docRow][row - 1] || 0;
@@ -1182,7 +1182,7 @@ var EditSession = function(text, mode) {
// Clamp docColumn.
if (this.$useWrapMode) {
- column = wrapData[docRow][row]
+ column = wrapData[docRow][row];
if (docColumn >= column) {
// We remove one character at the end such that the docColumn
// position returned is not associated to the next row on the
@@ -1237,11 +1237,11 @@ var EditSession = function(text, mode) {
}
return [screenRow, screenRowOffset];
- }
+ };
this.documentToScreenRow = function(docRow, docColumn) {
return this.$documentToScreenRow(docRow, docColumn)[0];
- }
+ };
this.documentToScreenPosition = function(pos, column) {
var str;
@@ -1300,7 +1300,7 @@ var EditSession = function(text, mode) {
screenRows += this.$wrapData[row].length + 1;
}
return screenRows;
- }
+ };
// For every keystroke this gets called once per char in the whole doc!!
// Wouldn't hurt to make it a bit faster for c >= 0x1100
diff --git a/lib/ace/defaults.js b/lib/ace/environment.js
similarity index 76%
rename from lib/ace/defaults.js
rename to lib/ace/environment.js
index bd217cd1..694fe978 100644
--- a/lib/ace/defaults.js
+++ b/lib/ace/environment.js
@@ -1,5 +1,4 @@
-/* vim:ts=4:sts=4:sw=4:
- * ***** BEGIN LICENSE BLOCK *****
+/* ***** 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
@@ -12,15 +11,14 @@
* for the specific language governing rights and limitations under the
* License.
*
- * The Original Code is Ajax.org Code Editor (ACE).
+ * The Original Code is DomTemplate.
*
- * 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 of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- * Irakli Gozalishvili (http://jeditoolkit.com)
+ * Joe Walker (jwalker@mozilla.com) (original author)
*
* 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
@@ -38,14 +36,19 @@
define(function(require, exports, module) {
-var settings = require("ace/settings/default-settings")
-exports.startup = function startup(data, reason) {
- settings.startup(data, reason)
-}
+var settings = require("ace/settings").settings;
-exports.shutdown = function shutdown(data, reason) {
- settings.shutdown(data, reason)
-}
+/**
+* Create an environment object
+*/
+function create() {
+ return {
+ settings: settings
+ };
+};
-})
+exports.create = create;
+
+
+});
diff --git a/lib/ace/index.js b/lib/ace/index.js
new file mode 100644
index 00000000..1061859e
--- /dev/null
+++ b/lib/ace/index.js
@@ -0,0 +1,58 @@
+/* vim:ts=4:sts=4:sw=4:
+ * ***** 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):
+ * Joe Walker (jwalker@mozilla.com)
+ * Irakli Gozalishvili (http://jeditoolkit.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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+
+exports.startup = function startup(data) {
+ require("ace/settings").startup(data);
+ require("ace/commands/settings").startup(data);
+ require('ace/commands/default_commands').startup(data);
+ require("ace/settings/default-settings").startup(data);
+};
+
+exports.shutdown = function shutdown(data) {
+ require("ace/settings/default-settings").shutdown(data);
+ require('ace/commands/default_commands').shutdown(data);
+ require("ace/commands/settings").shutdown(data);
+ require("ace/settings").shutdown(data);
+};
+
+
+});
diff --git a/lib/ace/keyboard/hash_handler.js b/lib/ace/keyboard/hash_handler.js
index f968b39b..cda6a351 100644
--- a/lib/ace/keyboard/hash_handler.js
+++ b/lib/ace/keyboard/hash_handler.js
@@ -38,7 +38,7 @@
define(function(require, exports, module) {
-var keyUtil = require("pilot/keys");
+var keyUtil = require("ace/keys");
function HashHandler(config) {
this.setConfig(config);
@@ -100,17 +100,17 @@ function HashHandler(config) {
if (hashId != 0 || keyCode != 0) {
return {
command: (this.$config.reverse[hashId] || {})[textOrKey]
- }
+ };
} else {
return {
command: "inserttext",
args: {
text: textOrKey
}
- }
+ };
}
- }
-}).call(HashHandler.prototype)
+ };
+}).call(HashHandler.prototype);
exports.HashHandler = HashHandler;
});
diff --git a/lib/ace/keyboard/keybinding.js b/lib/ace/keyboard/keybinding.js
index 93fc3fa8..b37b8723 100644
--- a/lib/ace/keyboard/keybinding.js
+++ b/lib/ace/keyboard/keybinding.js
@@ -38,17 +38,23 @@
define(function(require, exports, module) {
-var useragent = require("pilot/useragent");
-var keyUtil = require("pilot/keys");
-var event = require("pilot/event");
-var settings = require("pilot/settings").settings;
-var canon = require("pilot/canon");
-require("ace/commands/default_commands");
+
+var useragent = require('pilot/useragent');
+var event = require('pilot/event');
+var typecheck = require('pilot/typecheck');
+
+var keyUtil = require('ace/keys');
+var settings = require('ace/settings').settings;
+var Requisition = require('gcli/index').Requisition;
var KeyBinding = function(editor) {
this.$editor = editor;
this.$data = { };
this.$keyboardHandler = null;
+
+ // TODO: This is WRONG: we should be taking the env passed in to setup
+ this.$env = { editor: this.$editor };
+ this.$requisition = new Requisition(this.$env);
};
(function() {
@@ -64,8 +70,7 @@ var KeyBinding = function(editor) {
};
this.$callKeyboardHandler = function (e, hashId, keyOrText, keyCode) {
- var env = {editor: this.$editor},
- toExecute;
+ var toExecute;
if (this.$keyboardHandler) {
toExecute =
@@ -76,21 +81,23 @@ var KeyBinding = function(editor) {
if (!toExecute || !toExecute.command) {
if (hashId != 0 || keyCode != 0) {
toExecute = {
- command: canon.findKeyCommand(env, "editor", hashId, keyOrText)
- }
+ command: findKeyCommand(hashId, keyOrText),
+ args: { }
+ };
} else {
toExecute = {
command: "inserttext",
- args: {
- text: keyOrText
- }
- }
+ args: { text: keyOrText }
+ };
}
}
if (toExecute) {
- var success = canon.exec(toExecute.command,
- env, "editor", toExecute.args);
+ var success = this.$requisition.exec({
+ typed: toExecute.command,
+ args: toExecute.args
+ });
+
if (success) {
return event.stopEvent(e);
}
@@ -104,9 +111,68 @@ var KeyBinding = function(editor) {
this.onTextInput = function(text) {
this.$callKeyboardHandler({}, 0, text, 0);
- }
+ };
}).call(KeyBinding.prototype);
exports.KeyBinding = KeyBinding;
+
+
+/**
+* A lookup has for command key bindings.
+*/
+var commmandKeyBinding = { };
+
+function findKeyCommand(hashId, textOrKey) {
+ // Convert keyCode to the string representation.
+ if (typecheck.isNumber(textOrKey)) {
+ textOrKey = keyUtil.keyCodeToString(textOrKey);
+ }
+
+ return commmandKeyBinding[hashId] && commmandKeyBinding[hashId][textOrKey];
+}
+
+function splitSafe(s, separator, limit, bLowerCase) {
+ return (bLowerCase && s.toLowerCase() || s)
+ .replace(/(?:^\s+|\n|\s+$)/g, "")
+ .split(new RegExp("[\\s ]*" + separator + "[\\s ]*", "g"), limit || 999);
+}
+
+var platform = useragent.isMac ? "mac" : "win";
+
+function bindCommand(bindKey, value) {
+
+ if (!bindKey.mac && bindKey.mac !== null) {
+ throw new Error('All key bindings must have a mac key binding');
+ }
+ if (!bindKey.win && bindKey.win !== null) {
+ throw new Error('All key bindings must have a windows key binding');
+ }
+ if (!bindKey[platform]) {
+ // No key mapping for this platform.
+ return;
+ }
+
+ bindKey[platform].split("|").forEach(function(keys) {
+ var key;
+ var hashId = 0;
+
+ var parts = splitSafe(keys, "\\-", null, true);
+ parts.forEach(function(part) {
+ if (keyUtil.KEY_MODS[part])
+ hashId = hashId | keyUtil.KEY_MODS[part];
+ else
+ key = part || "-"; // when empty, the splitSafe removed a '-'
+ });
+
+ if (commmandKeyBinding[hashId] == null) {
+ commmandKeyBinding[hashId] = {};
+ }
+ commmandKeyBinding[hashId][key] = value;
+ });
+}
+
+exports.bindCommand = bindCommand;
+
+
});
diff --git a/lib/ace/keyboard/keybinding/emacs.js b/lib/ace/keyboard/keybinding/emacs.js
index ce0cbc06..7d3f6966 100644
--- a/lib/ace/keyboard/keybinding/emacs.js
+++ b/lib/ace/keyboard/keybinding/emacs.js
@@ -122,7 +122,7 @@ var emacsState = {
{
name: "text",
match: 2,
- type: "text"
+ type: "string"
}
]
},
diff --git a/lib/ace/keyboard/state_handler.js b/lib/ace/keyboard/state_handler.js
index 5861ad23..a05b9424 100644
--- a/lib/ace/keyboard/state_handler.js
+++ b/lib/ace/keyboard/state_handler.js
@@ -213,7 +213,7 @@ StateHandler.prototype = {
return r;
}
-}
+};
/**
* This is a useful matching function and therefore is defined here so that
diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js
index 03120a35..5b57e8d6 100644
--- a/lib/ace/keyboard/textinput.js
+++ b/lib/ace/keyboard/textinput.js
@@ -165,7 +165,7 @@ var TextInput = function(parentNode, host) {
};
if (useragent.isIE) {
- event.addListener(text, "beforecopy", function(e) {
+ event.addListener(text, "beforecopy", function(e) {
var copyText = host.getCopyText();
if(copyText)
clipboardData.setData("Text", copyText);
@@ -179,7 +179,7 @@ var TextInput = function(parentNode, host) {
clipboardData.setData("Text", copyText);
host.onCut();
}
- event.preventDefault(e)
+ event.preventDefault(e);
}
});
}
@@ -225,12 +225,12 @@ var TextInput = function(parentNode, host) {
if(!tempStyle)
tempStyle = text.style.cssText;
text.style.cssText = 'position:fixed; z-index:1000;' +
- 'left:' + (mousePos.x - 2) + 'px; top:' + (mousePos.y - 2) + 'px;'
+ 'left:' + (mousePos.x - 2) + 'px; top:' + (mousePos.y - 2) + 'px;';
}
if (isEmpty)
text.value='';
- }
+ };
this.onContextMenuClose = function(){
setTimeout(function () {
@@ -240,7 +240,7 @@ var TextInput = function(parentNode, host) {
}
sendText();
}, 0);
- }
+ };
};
exports.TextInput = TextInput;
diff --git a/lib/ace/keys.js b/lib/ace/keys.js
new file mode 100644
index 00000000..4f8068c2
--- /dev/null
+++ b/lib/ace/keys.js
@@ -0,0 +1,118 @@
+/*! @license
+==========================================================================
+SproutCore -- JavaScript Application Framework
+copyright 2006-2009, Sprout Systems Inc., Apple Inc. and contributors.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+SproutCore and the SproutCore logo are trademarks of Sprout Systems, Inc.
+
+For more information about SproutCore, visit http://www.sproutcore.com
+
+
+==========================================================================
+@license */
+
+// Most of the following code is taken from SproutCore with a few changes.
+
+define(function(require, exports, module) {
+
+var oop = require("pilot/oop");
+
+/**
+ * Helper functions and hashes for key handling.
+ */
+var Keys = (function() {
+ var ret = {
+ MODIFIER_KEYS: {
+ 16: 'Shift', 17: 'Ctrl', 18: 'Alt', 224: 'Meta'
+ },
+
+ KEY_MODS: {
+ "ctrl": 1, "alt": 2, "option" : 2,
+ "shift": 4, "meta": 8, "command": 8
+ },
+
+ FUNCTION_KEYS : {
+ 8 : "Backspace",
+ 9 : "Tab",
+ 13 : "Return",
+ 19 : "Pause",
+ 27 : "Esc",
+ 32 : "Space",
+ 33 : "PageUp",
+ 34 : "PageDown",
+ 35 : "End",
+ 36 : "Home",
+ 37 : "Left",
+ 38 : "Up",
+ 39 : "Right",
+ 40 : "Down",
+ 44 : "Print",
+ 45 : "Insert",
+ 46 : "Delete",
+ 112: "F1",
+ 113: "F2",
+ 114: "F3",
+ 115: "F4",
+ 116: "F5",
+ 117: "F6",
+ 118: "F7",
+ 119: "F8",
+ 120: "F9",
+ 121: "F10",
+ 122: "F11",
+ 123: "F12",
+ 144: "Numlock",
+ 145: "Scrolllock"
+ },
+
+ PRINTABLE_KEYS: {
+ 32: ' ', 48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5',
+ 54: '6', 55: '7', 56: '8', 57: '9', 59: ';', 61: '=', 65: 'a',
+ 66: 'b', 67: 'c', 68: 'd', 69: 'e', 70: 'f', 71: 'g', 72: 'h',
+ 73: 'i', 74: 'j', 75: 'k', 76: 'l', 77: 'm', 78: 'n', 79: 'o',
+ 80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v',
+ 87: 'w', 88: 'x', 89: 'y', 90: 'z', 107: '+', 109: '-', 110: '.',
+ 188: ',', 190: '.', 191: '/', 192: '`', 219: '[', 220: '\\',
+ 221: ']', 222: '\"'
+ }
+ };
+
+ // A reverse map of FUNCTION_KEYS
+ for (i in ret.FUNCTION_KEYS) {
+ var name = ret.FUNCTION_KEYS[i].toUpperCase();
+ ret[name] = parseInt(i, 10);
+ }
+
+ // Add the MODIFIER_KEYS, FUNCTION_KEYS and PRINTABLE_KEYS to the KEY
+ // variables as well.
+ oop.mixin(ret, ret.MODIFIER_KEYS);
+ oop.mixin(ret, ret.PRINTABLE_KEYS);
+ oop.mixin(ret, ret.FUNCTION_KEYS);
+
+ return ret;
+})();
+oop.mixin(exports, Keys);
+
+exports.keyCodeToString = function(keyCode) {
+ return (Keys[keyCode] || String.fromCharCode(keyCode)).toLowerCase();
+};
+
+});
diff --git a/lib/ace/layer/gutter.js b/lib/ace/layer/gutter.js
index b4354b5b..5edf038d 100644
--- a/lib/ace/layer/gutter.js
+++ b/lib/ace/layer/gutter.js
@@ -61,7 +61,7 @@ var Gutter = function(parentEl) {
if (!this.$decorations[row])
this.$decorations[row] = "";
this.$decorations[row] += " ace_" + className;
- }
+ };
this.removeGutterDecoration = function(row, className){
this.$decorations[row] = this.$decorations[row].replace(" ace_" + className, "");
@@ -73,12 +73,12 @@ var Gutter = function(parentEl) {
this.setAnnotations = function(annotations) {
// iterate over sparse array
- this.$annotations = [];
+ this.$annotations = [];
for (var row in annotations) if (annotations.hasOwnProperty(row)) {
var rowAnnotations = annotations[row];
if (!rowAnnotations)
continue;
-
+
var rowInfo = this.$annotations[row] = {
text: []
};
@@ -112,7 +112,8 @@ var Gutter = function(parentEl) {
"' title='", annotation.text.join("\n"),
"' style='height:", this.session.getRowHeight(config, i), "px;'>", (i+1), "");
}
- this.element = dom.setInnerHtml(this.element, html.join(""));
+
+ this.element = dom.rebuildWith(this.element, html.join(""));
this.element.style.height = config.minHeight + "px";
};
diff --git a/lib/ace/layer/marker.js b/lib/ace/layer/marker.js
index 028bef33..c58422a9 100644
--- a/lib/ace/layer/marker.js
+++ b/lib/ace/layer/marker.js
@@ -53,7 +53,7 @@ var Marker = function(parentEl) {
this.setSession = function(session) {
this.session = session;
};
-
+
this.setMarkers = function(markers) {
this.markers = markers;
};
@@ -65,7 +65,7 @@ var Marker = function(parentEl) {
this.config = config;
- var html = [];
+ var html = [];
for ( var key in this.markers) {
var marker = this.markers[key];
@@ -76,7 +76,7 @@ var Marker = function(parentEl) {
if (marker.renderer) {
var top = this.$getTop(range.start.row, config);
- var left = Math.round(range.start.column * config.characterWidth);
+ var left = Math.round(range.start.column * config.characterWidth);
marker.renderer(html, range, left, top, config);
}
else if (range.isMultiLine()) {
@@ -90,7 +90,7 @@ var Marker = function(parentEl) {
this.drawSingleLineMarker(html, range, marker.clazz, config);
}
}
- this.element = dom.setInnerHtml(this.element, html.join(""));
+ this.element = dom.rebuildWith(this.element, html.join(""));
};
this.$getTop = function(row, layerConfig) {
diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js
index a4fdee3d..80eb051d 100644
--- a/lib/ace/layer/text.js
+++ b/lib/ace/layer/text.js
@@ -195,7 +195,7 @@ var Text = function(parentEl) {
var html = [];
this.$renderLine(html, i, tokens[i-first].tokens);
- lineElement = dom.setInnerHtml(lineElement, html.join(""));
+ lineElement = dom.rebuildWith(lineElement, html.join(""));
lineElement.style.height =
this.session.getRowHeight(config, i) + "px";
}
@@ -249,7 +249,7 @@ var Text = function(parentEl) {
var html = [];
if (tokens.length > row-firstRow)
this.$renderLine(html, row, tokens[row-firstRow].tokens);
- // don't use setInnerHtml since we are working with an empty DIV
+ // don't use dom.rebuildWith since we are working with an empty DIV
lineEl.innerHTML = html.join("");
fragment.appendChild(lineEl);
}
@@ -261,7 +261,7 @@ var Text = function(parentEl) {
this.config = config;
var html = [];
- var tokens = this.session.getTokens(config.firstRow, config.lastRow)
+ var tokens = this.session.getTokens(config.firstRow, config.lastRow);
var fragment = this.$renderLinesFragment(config, config.firstRow, config.lastRow);
// Clear the current content of the element and add the rendered fragment.
@@ -299,11 +299,11 @@ var Text = function(parentEl) {
var space = new Array(c.length+1).join(self.SPACE_CHAR);
return "" + space + "";
} else {
- return " "
+ return " ";
}
} else {
screenColumn += 1;
- return "" + c + ""
+ return "" + c + "";
}
});
screenColumn += value.length;
diff --git a/lib/ace/mode/textile_highlight_rules.js b/lib/ace/mode/textile_highlight_rules.js
index b005d1b7..148d2be8 100644
--- a/lib/ace/mode/textile_highlight_rules.js
+++ b/lib/ace/mode/textile_highlight_rules.js
@@ -46,7 +46,7 @@ var TextileHighlightRules = function()
var phraseModifiers = lang.arrayToMap(
("_|*|__|**|??|-|+|^|%|@").split("|")
);
-
+
var blockModifiers = lang.arrayToMap(
("h1|h2|h3|h4|h5|h6|bq|p|bc|pre").split("|")
);
@@ -56,7 +56,7 @@ var TextileHighlightRules = function()
("-|--|(tm)|(r)|(c)").split("|")
);
*/
-
+
this.$rules = {
"start" : [
{
@@ -77,7 +77,7 @@ var TextileHighlightRules = function()
{
token : "keyword",
regex : "\\. ",
- next : "start",
+ next : "start"
},
{
token : "keyword",
diff --git a/lib/ace/plugin_manager.js b/lib/ace/plugin_manager.js
new file mode 100644
index 00000000..8d6e4999
--- /dev/null
+++ b/lib/ace/plugin_manager.js
@@ -0,0 +1,159 @@
+/* ***** 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 Skywriter.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Kevin Dangoor (kdangoor@mozilla.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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var Promise = require("ace/promise").Promise;
+
+exports.REASONS = {
+ APP_STARTUP: 1,
+ APP_SHUTDOWN: 2,
+ PLUGIN_ENABLE: 3,
+ PLUGIN_DISABLE: 4,
+ PLUGIN_INSTALL: 5,
+ PLUGIN_UNINSTALL: 6,
+ PLUGIN_UPGRADE: 7,
+ PLUGIN_DOWNGRADE: 8
+};
+
+exports.Plugin = function(name) {
+ this.name = name;
+ this.status = this.INSTALLED;
+};
+
+exports.Plugin.prototype = {
+ /**
+ * constants for the state
+ */
+ NEW: 0,
+ INSTALLED: 1,
+ REGISTERED: 2,
+ STARTED: 3,
+ UNREGISTERED: 4,
+ SHUTDOWN: 5,
+
+ install: function(data, reason) {
+ var pr = new Promise();
+ if (this.status > this.NEW) {
+ pr.resolve(this);
+ return pr;
+ }
+ require([this.name], function(pluginModule) {
+ if (pluginModule.install) {
+ pluginModule.install(data, reason);
+ }
+ this.status = this.INSTALLED;
+ pr.resolve(this);
+ }.bind(this));
+ return pr;
+ },
+
+ register: function(data, reason) {
+ var pr = new Promise();
+ if (this.status != this.INSTALLED) {
+ pr.resolve(this);
+ return pr;
+ }
+ require([this.name], function(pluginModule) {
+ if (pluginModule.register) {
+ pluginModule.register(data, reason);
+ }
+ this.status = this.REGISTERED;
+ pr.resolve(this);
+ }.bind(this));
+ return pr;
+ },
+
+ startup: function(data, reason) {
+ reason = reason || exports.REASONS.APP_STARTUP;
+ var pr = new Promise();
+ if (this.status != this.REGISTERED) {
+ pr.resolve(this);
+ return pr;
+ }
+ require([this.name], function(pluginModule) {
+ if (pluginModule.startup) {
+ pluginModule.startup(data, reason);
+ }
+ this.status = this.STARTED;
+ pr.resolve(this);
+ }.bind(this));
+ return pr;
+ },
+
+ shutdown: function(data, reason) {
+ if (this.status != this.STARTED) {
+ return;
+ }
+ pluginModule = require(this.name);
+ if (pluginModule.shutdown) {
+ pluginModule.shutdown(data, reason);
+ }
+ }
+};
+
+exports.PluginCatalog = function() {
+ this.plugins = {};
+};
+
+exports.PluginCatalog.prototype = {
+ registerPlugins: function(pluginList, data, reason) {
+ var registrationPromises = [];
+ pluginList.forEach(function(pluginName) {
+ var plugin = this.plugins[pluginName];
+ if (plugin === undefined) {
+ plugin = new exports.Plugin(pluginName);
+ this.plugins[pluginName] = plugin;
+ registrationPromises.push(plugin.register(data, reason));
+ }
+ }.bind(this));
+ return Promise.group(registrationPromises);
+ },
+
+ startupPlugins: function(data, reason) {
+ var startupPromises = [];
+ for (var pluginName in this.plugins) {
+ var plugin = this.plugins[pluginName];
+ startupPromises.push(plugin.startup(data, reason));
+ }
+ return Promise.group(startupPromises);
+ }
+};
+
+exports.catalog = new exports.PluginCatalog();
+
+});
diff --git a/lib/ace/promise.js b/lib/ace/promise.js
new file mode 100644
index 00000000..37f1832b
--- /dev/null
+++ b/lib/ace/promise.js
@@ -0,0 +1,247 @@
+/* ***** 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 Mozilla Skywriter.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Joe Walker (jwalker@mozilla.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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var console = require("pilot/console");
+
+/**
+ * A promise can be in one of 2 states.
+ * The ERROR and SUCCESS states are terminal, the PENDING state is the only
+ * start state.
+ */
+var ERROR = -1;
+var PENDING = 0;
+var SUCCESS = 1;
+
+/**
+ * We give promises and ID so we can track which are outstanding
+ */
+var _nextId = 0;
+
+/**
+ * Outstanding promises. Handy list for debugging only.
+ */
+var _outstanding = [];
+
+/**
+ * Recently resolved promises. Also for debugging only.
+ */
+var _recent = [];
+
+/**
+ * Create an unfulfilled promise
+ */
+Promise = function () {
+ this._status = PENDING;
+ this._value = undefined;
+ this._onSuccessHandlers = [];
+ this._onErrorHandlers = [];
+
+ // Debugging help
+ this._id = _nextId++;
+ _outstanding[this._id] = this;
+};
+
+/**
+ * Yeay for RTTI.
+ */
+Promise.prototype.isPromise = true;
+
+/**
+ * Have we either been resolve()ed or reject()ed?
+ */
+Promise.prototype.isComplete = function() {
+ return this._status != PENDING;
+};
+
+/**
+ * Have we resolve()ed?
+ */
+Promise.prototype.isResolved = function() {
+ return this._status == SUCCESS;
+};
+
+/**
+ * Have we reject()ed?
+ */
+Promise.prototype.isRejected = function() {
+ return this._status == ERROR;
+};
+
+/**
+ * Take the specified action of fulfillment of a promise, and (optionally)
+ * a different action on promise rejection.
+ */
+Promise.prototype.then = function(onSuccess, onError) {
+ if (typeof onSuccess === 'function') {
+ if (this._status === SUCCESS) {
+ onSuccess.call(null, this._value);
+ } else if (this._status === PENDING) {
+ this._onSuccessHandlers.push(onSuccess);
+ }
+ }
+
+ if (typeof onError === 'function') {
+ if (this._status === ERROR) {
+ onError.call(null, this._value);
+ } else if (this._status === PENDING) {
+ this._onErrorHandlers.push(onError);
+ }
+ }
+
+ return this;
+};
+
+/**
+ * Like then() except that rather than returning this we return
+ * a promise which
+ */
+Promise.prototype.chainPromise = function(onSuccess) {
+ var chain = new Promise();
+ chain._chainedFrom = this;
+ this.then(function(data) {
+ try {
+ chain.resolve(onSuccess(data));
+ } catch (ex) {
+ chain.reject(ex);
+ }
+ }, function(ex) {
+ chain.reject(ex);
+ });
+ return chain;
+};
+
+/**
+ * Supply the fulfillment of a promise
+ */
+Promise.prototype.resolve = function(data) {
+ return this._complete(this._onSuccessHandlers, SUCCESS, data, 'resolve');
+};
+
+/**
+ * Renege on a promise
+ */
+Promise.prototype.reject = function(data) {
+ return this._complete(this._onErrorHandlers, ERROR, data, 'reject');
+};
+
+/**
+ * Internal method to be called on resolve() or reject().
+ * @private
+ */
+Promise.prototype._complete = function(list, status, data, name) {
+ // Complain if we've already been completed
+ if (this._status != PENDING) {
+ console.group('Promise already closed');
+ console.error('Attempted ' + name + '() with ', data);
+ console.error('Previous status = ', this._status,
+ ', previous value = ', this._value);
+ console.trace();
+
+ console.groupEnd();
+ return this;
+ }
+
+ this._status = status;
+ this._value = data;
+
+ // Call all the handlers, and then delete them
+ list.forEach(function(handler) {
+ handler.call(null, this._value);
+ }, this);
+ this._onSuccessHandlers.length = 0;
+ this._onErrorHandlers.length = 0;
+
+ // Remove the given {promise} from the _outstanding list, and add it to the
+ // _recent list, pruning more than 20 recent promises from that list.
+ delete _outstanding[this._id];
+ _recent.push(this);
+ while (_recent.length > 20) {
+ _recent.shift();
+ }
+
+ return this;
+};
+
+/**
+ * Takes an array of promises and returns a promise that that is fulfilled once
+ * all the promises in the array are fulfilled
+ * @param group The array of promises
+ * @return the promise that is fulfilled when all the array is fulfilled
+ */
+Promise.group = function(promiseList) {
+ if (!(promiseList instanceof Array)) {
+ promiseList = Array.prototype.slice.call(arguments);
+ }
+
+ // If the original array has nothing in it, return now to avoid waiting
+ if (promiseList.length === 0) {
+ return new Promise().resolve([]);
+ }
+
+ var groupPromise = new Promise();
+ var results = [];
+ var fulfilled = 0;
+
+ var onSuccessFactory = function(index) {
+ return function(data) {
+ results[index] = data;
+ fulfilled++;
+ // If the group has already failed, silently drop extra results
+ if (groupPromise._status !== ERROR) {
+ if (fulfilled === promiseList.length) {
+ groupPromise.resolve(results);
+ }
+ }
+ };
+ };
+
+ promiseList.forEach(function(promise, index) {
+ var onSuccess = onSuccessFactory(index);
+ var onError = groupPromise.reject.bind(groupPromise);
+ promise.then(onSuccess, onError);
+ });
+
+ return groupPromise;
+};
+
+exports.Promise = Promise;
+exports._outstanding = _outstanding;
+exports._recent = _recent;
+
+});
diff --git a/lib/ace/settings.js b/lib/ace/settings.js
new file mode 100644
index 00000000..fae12163
--- /dev/null
+++ b/lib/ace/settings.js
@@ -0,0 +1,380 @@
+/* vim:ts=4:sts=4:sw=4:
+ * ***** 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 Mozilla Skywriter.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Joe Walker (jwalker@mozilla.com)
+ * Julian Viereck (jviereck@mozilla.com)
+ * Kevin Dangoor (kdangoor@mozilla.com)
+ * Irakli Gozalishvili (http://jeditoolkit.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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+
+var console = require('pilot/console');
+var oop = require('pilot/oop');
+var types = require('gcli/types');
+var EventEmitter = require('pilot/event_emitter').EventEmitter;
+
+var SelectionType = require('gcli/types').SelectionType;
+var DeferredType = require('gcli/types').DeferredType;
+var Argument = require('gcli/argument').Argument;
+
+
+/**
+ * Create a new setting.
+ * @param settingSpec An object literal that looks like this:
+ * {
+ * name: 'thing',
+ * description: 'Thing is an example setting',
+ * type: 'string',
+ * defaultValue: 'something'
+ * }
+ */
+function Setting(settingSpec, settings) {
+ this._settings = settings;
+
+ Object.keys(settingSpec).forEach(function(key) {
+ this[key] = settingSpec[key];
+ }, this);
+
+ this.type = types.getType(this.type);
+ if (this.type == null) {
+ throw new Error('In ' + this.name +
+ ': can\'t find type for: ' + JSON.stringify(settingSpec.type));
+ }
+
+ if (!this.name) {
+ throw new Error('Setting.name == undefined. Ignoring.', this);
+ }
+
+ if (!this.defaultValue === undefined) {
+ throw new Error('Setting.defaultValue == undefined', this);
+ }
+
+ if (this.onChange) {
+ this.on('change', this.onChange.bind(this));
+ }
+
+ this.set(this.defaultValue);
+}
+Setting.prototype = {
+ get: function() {
+ return this.value;
+ },
+
+ set: function(value) {
+ if (this.value === value) {
+ return;
+ }
+
+ this.value = value;
+ if (this._settings.persister) {
+ this._settings.persister.persistValue(this._settings, this.name, value);
+ }
+
+ this._dispatchEvent('change', { setting: this, value: value });
+ },
+
+ /**
+ * Reset the value of the key setting to it's default
+ */
+ resetValue: function() {
+ this.set(this.defaultValue);
+ }
+};
+oop.implement(Setting.prototype, EventEmitter);
+
+
+/**
+ * A base class for all the various methods of storing settings.
+ *
Usage:
+ *
+ * // Create manually, or require 'settings' from the container.
+ * // This is the manual version:
+ * // Add a new setting
+ * settings.addSetting({ name:'foo', ... });
+ * // Display the default value
+ * alert(settings.get('foo'));
+ * // Alter the value, which also publishes the change etc.
+ * settings.set('foo', 'bar');
+ * // Reset the value to the default
+ * settings.resetValue('foo');
+ *
+ * @constructor
+ */
+function Settings(persister) {
+ // Storage for deactivated values
+ this._deactivated = {};
+
+ // Storage for the active settings
+ this._settings = {};
+ // We often want sorted setting names. Cache
+ this._settingNames = [];
+
+ if (persister) {
+ this.setPersister(persister);
+ }
+};
+
+Settings.prototype = {
+ /**
+ * Function to add to the list of available settings.
+ *
Example usage:
+ *
+ * settings.addSetting({
+ * name: 'tabsize', // For use in settings.get('X')
+ * type: 'number', // To allow value checking.
+ * defaultValue: 4 // Default value for use when none is directly set
+ * });
+ *
+ * @param {object} settingSpec Object containing name/type/defaultValue members.
+ */
+ addSetting: function(settingSpec) {
+ var setting = new Setting(settingSpec, this);
+ this._settings[setting.name] = setting;
+ this._settingNames.push(setting.name);
+ this._settingNames.sort();
+ },
+
+ addSettings: function addSettings(settings) {
+ Object.keys(settings).forEach(function (name) {
+ var setting = settings[name];
+ if (!('name' in setting)) setting.name = name;
+ this.addSetting(setting);
+ }, this);
+ },
+
+ removeSetting: function(setting) {
+ var name = (typeof setting === 'string' ? setting : setting.name);
+ setting = this._settings[name];
+ delete this._settings[name];
+ util.arrayRemove(this._settingNames, name);
+ settings.removeAllListeners('change');
+ },
+
+ removeSettings: function removeSettings(settings) {
+ Object.keys(settings).forEach(function(name) {
+ var setting = settings[name];
+ if (!('name' in setting)) setting.name = name;
+ this.removeSettings(setting);
+ }, this);
+ },
+
+ getSettings: function() {
+ return Object.keys(this._settings).map(function(name) {
+ return this._settings[name];
+ }, this);
+ },
+
+ getSettingNames: function() {
+ return this._settingNames;
+ },
+
+ getSetting: function(name) {
+ return this._settings[name];
+ },
+
+ /**
+ * A Persister is able to store settings. It is an object that defines
+ * two functions:
+ * loadInitialValues(settings) and persistValue(settings, key, value).
+ */
+ setPersister: function(persister) {
+ this._persister = persister;
+ if (persister) {
+ persister.loadInitialValues(this);
+ }
+ },
+
+ resetAll: function() {
+ this.getSettingNames().forEach(function(key) {
+ this.resetValue(key);
+ }, this);
+ },
+
+ /**
+ * Retrieve a list of the known settings and their values
+ */
+ _list: function() {
+ var reply = [];
+ this.getSettingNames().forEach(function(setting) {
+ reply.push({
+ 'key': setting,
+ 'value': this.getSetting(setting).get()
+ });
+ }, this);
+ return reply;
+ },
+
+ /**
+ * Prime the local cache with the defaults.
+ */
+ _loadDefaultValues: function() {
+ this._loadFromObject(this._getDefaultValues());
+ },
+
+ /**
+ * Utility to load settings from an object
+ */
+ _loadFromObject: function(data) {
+ // We iterate over data rather than keys so we don't forget values
+ // which don't have a setting yet.
+ for (var key in data) {
+ if (data.hasOwnProperty(key)) {
+ var setting = this._settings[key];
+ if (setting) {
+ var value = setting.type.parseString(data[key]);
+ this.set(key, value);
+ } else {
+ this.set(key, data[key]);
+ }
+ }
+ }
+ },
+
+ /**
+ * Utility to grab all the settings and export them into an object
+ */
+ _saveToObject: function() {
+ return this.getSettingNames().map(function(key) {
+ return this._settings[key].type.stringify(this.get(key));
+ }.bind(this));
+ },
+
+ /**
+ * The default initial settings
+ */
+ _getDefaultValues: function() {
+ return this.getSettingNames().map(function(key) {
+ return this._settings[key].spec.defaultValue;
+ }.bind(this));
+ }
+};
+exports.settings = new Settings();
+
+/**
+ * Save the settings in a cookie
+ * This code has not been tested since reboot
+ * @constructor
+ */
+function CookiePersister() {
+};
+
+CookiePersister.prototype = {
+ loadInitialValues: function(settings) {
+ settings._loadDefaultValues();
+ var data = cookie.get('settings');
+ settings._loadFromObject(JSON.parse(data));
+ },
+
+ persistValue: function(settings, key, value) {
+ try {
+ var stringData = JSON.stringify(settings._saveToObject());
+ cookie.set('settings', stringData);
+ } catch (ex) {
+ console.error('Unable to JSONify the settings! ' + ex);
+ return;
+ }
+ }
+};
+
+exports.CookiePersister = CookiePersister;
+
+
+/**
+ * This relies on us using settingValue in the same event as setting
+ * The alternative is to have some central place where we store the current
+ * command line, but this might be a lesser evil for now.
+ */
+var lastSetting;
+
+/**
+ * Select from the available settings
+ */
+var setting = new SelectionType({
+ name: 'setting',
+ data: function() {
+ return env.settings.getSettings();
+ },
+ noMatch: function() {
+ lastSetting = null;
+ },
+ stringify: function(setting) {
+ lastSetting = setting;
+ return SelectionType.prototype.stringify.call(this, setting);
+ },
+ parse: function(arg) {
+ var conversion = SelectionType.prototype.parse.call(this, arg);
+ lastSetting = conversion.value;
+ return conversion;
+ }
+});
+
+/**
+ * Something of a hack to allow the set command to give a clearer definition
+ * of the type to the command line.
+ */
+var settingValue = new DeferredType({
+ name: 'settingValue',
+ defer: function() {
+ if (lastSetting) {
+ return lastSetting.type;
+ }
+ else {
+ // console.error('Missing lastSetting. Defaulting to blank');
+ return types.getType('blank');
+ }
+ }
+});
+
+var env;
+
+
+/**
+ * Registration and de-registration.
+ */
+exports.startup = function(data) {
+ env = data.env;
+ types.registerType(setting);
+ types.registerType(settingValue);
+};
+
+exports.shutdown = function(data) {
+ types.unregisterType(setting);
+ types.unregisterType(settingValue);
+};
+
+
+});
diff --git a/lib/ace/settings/default-settings.js b/lib/ace/settings/default-settings.js
index 4e5e0fdf..e63ff6f9 100644
--- a/lib/ace/settings/default-settings.js
+++ b/lib/ace/settings/default-settings.js
@@ -38,16 +38,8 @@
define(function(require, exports, module) {
-var types = require('pilot/types')
-var SelectionType = require('pilot/types/basic').SelectionType
-var env
-
-var settingTypes = {
- selectionStyle: new SelectionType({
- data: [ 'line', 'text' ]
- })
-}
+var env;
var settings = {
printMargin: {
@@ -55,43 +47,42 @@ var settings = {
type: 'number',
defaultValue: 80,
onChange: function onChange(event) {
- if (env.editor) env.editor.setPrintMarginColumn(event.value)
+ if (env.editor) env.editor.setPrintMarginColumn(event.value);
}
},
showIvisibles: {
description: 'Whether or not to show invisible characters.',
- type: 'bool',
+ type: 'boolean',
defaultValue: false,
onChange: function onChange(event) {
- if (env.editor) env.editor.setShowInvisibles(event.value)
+ if (env.editor) env.editor.setShowInvisibles(event.value);
}
},
highlightActiveLine: {
description: 'Whether or not highlight active line.',
- type: 'bool',
+ type: 'boolean',
defaultValue: true,
onChange: function onChange(event) {
- if (env.editor) env.editor.setHighlightActiveLine(event.value)
+ if (env.editor) env.editor.setHighlightActiveLine(event.value);
}
},
selectionStyle: {
description: 'Type of text selection.',
- type: 'selectionStyle',
+ type: { name: 'selection', data: [ 'line', 'text' ] },
defaultValue: 'line',
onChange: function onChange(event) {
- if (env.editor) env.editor.setSelectionStyle(event.value)
+ if (env.editor) env.editor.setSelectionStyle(event.value);
}
}
-}
+};
-exports.startup = function startup(data, reason) {
- env = data.env
- types.registerTypes(settingTypes)
- data.env.settings.addSettings(settings)
-}
+exports.startup = function startup(data) {
+ env = data.env;
+ data.env.settings.addSettings(settings);
+};
-exports.shutdown = function shutdown(data, reason) {
- data.env.settings.removeSettings(settings)
-}
+exports.shutdown = function shutdown(data) {
+ data.env.settings.removeSettings(settings);
+};
-})
+});
diff --git a/lib/ace/test/event_emitter_test.js b/lib/ace/test/event_emitter_test.js
index 6b971751..a6f78d59 100644
--- a/lib/ace/test/event_emitter_test.js
+++ b/lib/ace/test/event_emitter_test.js
@@ -55,17 +55,32 @@ module.exports = {
var called = false;
emitter.addEventListener("juhu", function(e) {
- called = true;
- assert.equal(e.type, "juhu");
+ called = true;
+ assert.equal(e.type, "juhu");
});
emitter._dispatchEvent("juhu");
assert.ok(called);
+ },
+
+ "test: single dispatch" : function() {
+ var real = new Emitter();
+ var ignored = new Emitter();
+
+ var calls = 0;
+ real.addEventListener("juhu", function(e) {
+ calls++;
+ assert.equal(e.type, "juhu");
+ });
+
+ real._dispatchEvent("juhu");
+ real._dispatchEvent("juhu");
+
+ assert.equal(2, calls);
}
};
-});
-
if (typeof module !== "undefined" && module === require.main) {
require("asyncjs/test").testcase(module.exports).exec()
-}
\ No newline at end of file
+}
+
diff --git a/lib/ace/test/tests.html b/lib/ace/test/tests.html
index 2af7ea55..bccc7388 100644
--- a/lib/ace/test/tests.html
+++ b/lib/ace/test/tests.html
@@ -29,7 +29,7 @@
require({
paths: {
ace: "../lib/ace",
- cockpit: "../support/cockpit/lib/cockpit",
+ gcli: "../support/gcli/lib/gcli",
pilot: "../support/pilot/lib/pilot"
},
packages : [{
diff --git a/support/cockpit b/support/cockpit
index 33f02ab3..22ec4140 160000
--- a/support/cockpit
+++ b/support/cockpit
@@ -1 +1 @@
-Subproject commit 33f02ab3af5d755c98b3c58309ac2c62fc6de736
+Subproject commit 22ec41400312eaffe89131e6728c60bd94dff471
diff --git a/support/pilot b/support/pilot
deleted file mode 160000
index 99f88766..00000000
--- a/support/pilot
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 99f887668f74e4670c29c8652f630d024e76c5ee