diff --git a/demo/kitchen-sink/demo.js b/demo/kitchen-sink/demo.js index 7a2f2e76..5411a68d 100644 --- a/demo/kitchen-sink/demo.js +++ b/demo/kitchen-sink/demo.js @@ -47,6 +47,8 @@ var env = {}; var dom = require("ace/lib/dom"); var net = require("ace/lib/net"); +var lang = require("ace/lib/lang"); +var useragent = require("ace/lib/useragent"); var event = require("ace/lib/event"); var theme = require("ace/theme/textmate"); @@ -737,10 +739,41 @@ function singleLineEditor(el) { editor.setHighlightActiveLine(false); editor.setShowPrintMargin(false); editor.renderer.setShowGutter(false); - // editor.renderer.setHighlightGutterLine(false); + editor.renderer.setHighlightGutterLine(false); return editor; }; +/** simple statusbar **/ +var editor = env.editor; +var statusBarEl = dom.createElement("div"); +statusBarEl.style.cssText = "color:gray;position:absolute;right:0;border-left:1px solid"; +cmdLine.container.appendChild(statusBarEl); +var statusUpdate = lang.deferredCall(function() { + var status = []; + function add(s, sep) {s && status.push(s, sep || "|")} + if (editor.$vimModeHandler) + add(editor.$vimModeHandler.getStatusText()); + else if (editor.commands.recording) + add("REC"); + + var c = editor.selection.lead; + add(c.row + ":" + c.column, " "); + if (!editor.selection.isEmpty()) { + var r = editor.getSelectionRange() + add("(" + (r.end.row - r.start.row) + ":" +(r.end.column - r.start.column) + ")"); + } + status.pop(); + statusBarEl.textContent = status.join(""); +}); + +env.editor.on("changeStatus", function() { + statusUpdate.schedule(200); +}); +env.editor.on("changeSelection", function() { + statusUpdate.schedule(200); +}); + + }); diff --git a/lib/ace/commands/command_manager.js b/lib/ace/commands/command_manager.js index 5eab67be..ee7c8561 100644 --- a/lib/ace/commands/command_manager.js +++ b/lib/ace/commands/command_manager.js @@ -60,9 +60,11 @@ oop.inherits(CommandManager, HashHandler); return retvalue === false ? false : true; }; - this.toggleRecording = function() { + this.toggleRecording = function(editor) { if (this.$inReplay) return; + + editor && editor._emit("changeStatus"); if (this.recording) { this.macro.pop(); this.removeEventListener("exec", this.$addCommandToMacro); @@ -74,8 +76,8 @@ oop.inherits(CommandManager, HashHandler); } if (!this.$addCommandToMacro) { this.$addCommandToMacro = function(e) { - this.macro.push([e.command, e.args]); - }.bind(this); + this.macro.push([e.command, e.args]); + }.bind(this); } this.oldMacro = this.macro; @@ -89,7 +91,7 @@ oop.inherits(CommandManager, HashHandler); return; if (this.recording) - return this.toggleRecording(); + return this.toggleRecording(editor); try { this.$inReplay = true; diff --git a/lib/ace/commands/command_manager_test.js b/lib/ace/commands/command_manager_test.js index 3ad11d59..71a37117 100644 --- a/lib/ace/commands/command_manager_test.js +++ b/lib/ace/commands/command_manager_test.js @@ -128,7 +128,7 @@ module.exports = { var called = ""; this.cm.addCommands({ togglerecording: function(editor) { - editor.cm.toggleRecording(); + editor.cm.toggleRecording(editor); }, replay: function(editor) { editor.cm.replay(); @@ -140,9 +140,14 @@ module.exports = { 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"); diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index c2140289..1811c34c 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -288,7 +288,7 @@ exports.commands = [{ }, { name: "togglerecording", bindKey: bindKey("Ctrl-Alt-E", "Command-Option-E"), - exec: function(editor) { editor.commands.toggleRecording(); }, + exec: function(editor) { editor.commands.toggleRecording(editor); }, readOnly: true }, { name: "replaymacro", diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 1b11a077..f8eb9636 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -531,6 +531,8 @@ var Editor = function(renderer, session) { var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp() this.session.highlight(re); + + this._emit("changeSelection"); }; this.$getSelectionHighLightRegexp = function() { diff --git a/lib/ace/keyboard/vim.js b/lib/ace/keyboard/vim.js index 00749bdb..98b80683 100644 --- a/lib/ace/keyboard/vim.js +++ b/lib/ace/keyboard/vim.js @@ -39,7 +39,6 @@ define(function(require, exports, module) { "use strict"; -var keyUtil = require("../lib/keys"); var cmds = require("./vim/commands"); var coreCommands = cmds.coreCommands; var util = require("./vim/maps/util"); @@ -88,7 +87,7 @@ exports.handler = { data.lastEvent = "keypress"; } }, - + handleKeyboard: function(data, hashId, key, keyCode, e) { // ignore command keys (shift, ctrl etc.) if (hashId != 0 && (key == "" || key == "\x00")) @@ -131,6 +130,7 @@ exports.handler = { editor.on("click", exports.onCursorMove); if (util.currentMode !== "insert") cmds.coreCommands.stop.exec(editor); + editor.$vimModeHandler = this; }, detach: function(editor) { @@ -139,7 +139,14 @@ exports.handler = { util.currentMode = "normal"; }, - actions: cmds.actions + actions: cmds.actions, + getStatusText: function() { + if (util.currentMode == "insert") + return "INSERT"; + if (util.onVisualMode) + return (util.onVisualLineMode ? "VISUAL LINE " : "VISUAL ") + cmds.inputBuffer.status; + return cmds.inputBuffer.status; + } }; diff --git a/lib/ace/keyboard/vim/commands.js b/lib/ace/keyboard/vim/commands.js index 85ab7f68..7c26ce32 100644 --- a/lib/ace/keyboard/vim/commands.js +++ b/lib/ace/keyboard/vim/commands.js @@ -304,6 +304,7 @@ var inputBuffer = exports.inputBuffer = { currentCmd: null, //currentMode: 0, currentCount: "", + status: "", // Types operator: null, @@ -378,6 +379,17 @@ var inputBuffer = exports.inputBuffer = { else { this.reset(); } + + if (this.waitingForParam || this.motion || this.operator) { + this.status += char; + } else if (this.currentCount) { + this.status = this.currentCount; + } else if (this.status) { + this.status = ""; + } else { + return; + } + editor._emit("changeStatus"); }, waitForParam: function(cmd) { @@ -462,6 +474,7 @@ var inputBuffer = exports.inputBuffer = { this.operator = null; this.motion = null; this.currentCount = ""; + this.status = ""; this.accepting = [NUMBER, OPERATOR, MOTION, ACTION]; this.idle = true; this.waitingForParam = null; diff --git a/lib/ace/keyboard/vim/maps/util.js b/lib/ace/keyboard/vim/maps/util.js index b8a27db4..1e8b3e2f 100644 --- a/lib/ace/keyboard/vim/maps/util.js +++ b/lib/ace/keyboard/vim/maps/util.js @@ -22,7 +22,7 @@ module.exports = { editor.unsetStyle('insert-mode'); editor.unsetStyle('normal-mode'); if (editor.commands.recording) - editor.commands.toggleRecording(); + editor.commands.toggleRecording(editor); editor.setOverwrite(false); }, insertMode: function(editor) { @@ -43,10 +43,10 @@ module.exports = { this.onInsertReplaySequence = null; this.normalMode(editor); } else { - editor._emit("vimMode", "insert"); + editor._emit("changeStatus"); // Record any movements, insertions in insert mode if(!editor.commands.recording) - editor.commands.toggleRecording(); + editor.commands.toggleRecording(editor); } }, normalMode: function(editor) { @@ -69,10 +69,10 @@ module.exports = { editor.keyBinding.$data.state = "start"; this.onVisualMode = false; this.onVisualLineMode = false; - editor._emit("changeVimMode", "normal"); + editor._emit("changeStatus"); // Save recorded keystrokes if (editor.commands.recording) { - editor.commands.toggleRecording(); + editor.commands.toggleRecording(editor); return editor.commands.macro; } else { @@ -91,7 +91,7 @@ module.exports = { editor.setStyle('insert-mode'); editor.unsetStyle('normal-mode'); - editor._emit("changeVimMode", "visual"); + editor._emit("changeStatus"); if (lineMode) { this.onVisualLineMode = true; } else {