From d09740f4947ef64c37bb2a36af34c786ff552726 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 8 Nov 2014 15:57:23 +0400 Subject: [PATCH] fix emacs universal argument --- lib/ace/ext/statusbar.js | 5 ++--- lib/ace/keyboard/emacs.js | 31 +++++++++++++++++++------------ lib/ace/keyboard/emacs_test.js | 3 --- lib/ace/keyboard/keybinding.js | 10 +++++++++- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/lib/ace/ext/statusbar.js b/lib/ace/ext/statusbar.js index 666febfa..5e5b0572 100644 --- a/lib/ace/ext/statusbar.js +++ b/lib/ace/ext/statusbar.js @@ -28,9 +28,8 @@ var StatusBar = function(editor, parentNode) { str && status.push(str, separator || "|"); } - if (editor.$vimModeHandler) - add(editor.$vimModeHandler.getStatusText()); - else if (editor.commands.recording) + add(editor.keyBinding.getStatusText(editor)); + if (editor.commands.recording) add("REC"); var c = editor.selection.lead; diff --git a/lib/ace/keyboard/emacs.js b/lib/ace/keyboard/emacs.js index 2b6bd2c4..945eddf3 100644 --- a/lib/ace/keyboard/emacs.js +++ b/lib/ace/keyboard/emacs.js @@ -164,6 +164,7 @@ exports.handler.detach = function(editor) { editor.commands.removeCommands(commands); editor.removeEventListener('copy', this.onCopy); editor.removeEventListener('paste', this.onPaste); + editor.$emacsModeHandler = null; }; var $kbSessionChange = function(e) { @@ -205,7 +206,7 @@ exports.handler.onCopy = function(e, editor) { if (editor.$handlesEmacsOnCopy) return; editor.$handlesEmacsOnCopy = true; exports.handler.commands.killRingSave.exec(editor); - delete editor.$handlesEmacsOnCopy; + editor.$handlesEmacsOnCopy = false; }; exports.handler.onPaste = function(e, editor) { @@ -238,12 +239,22 @@ exports.handler.bindKey = function(key, command) { }, this); }; +exports.handler.getStatusText = function(editor, data) { + var str = ""; + if (data.count) + str += data.count; + if (data.keyChain) + str += " " + data.keyChain + return str; +}; + exports.handler.handleKeyboard = function(data, hashId, key, keyCode) { // if keyCode == -1 a non-printable key was pressed, such as just // control. Handling those is currently not supported in this handler if (keyCode === -1) return undefined; var editor = data.editor; + editor._signal("changeStatus"); // insertstring data.count times if (hashId == -1) { editor.pushEmacsMark(); @@ -254,24 +265,17 @@ exports.handler.handleKeyboard = function(data, hashId, key, keyCode) { } } - if (key == "\x00") return undefined; - var modifier = eMods[hashId]; // CTRL + number / universalArgument for setting data.count - if (modifier == "c-" || data.universalArgument) { - var prevCount = String(data.count || 0); + if (modifier == "c-" || data.count) { var count = parseInt(key[key.length - 1]); if (typeof count === 'number' && !isNaN(count)) { - data.count = parseInt(prevCount + count); + data.count = Math.max(data.count, 0) || 0; + data.count = 10 * data.count + count; return {command: "null"}; - } else if (data.universalArgument) { - // if no number pressed use emacs defaults for universalArgument - // which is 4 - data.count = 4; } } - data.universalArgument = false; // this.commandKeyBinding maps key specs like "c-p" (for CTRL + P) to // command objects, for lookup key needs to include the modifier @@ -293,7 +297,9 @@ exports.handler.handleKeyboard = function(data, hashId, key, keyCode) { if (command === "null") return {command: "null"}; if (command === "universalArgument") { - data.universalArgument = true; + // if no number pressed emacs repeats action 4 times. + // minus sign is needed to allow next keypress to replace it + data.count = -4; return {command: "null"}; } @@ -607,6 +613,7 @@ exports.handler.addCommands({ keyboardQuit: function(editor) { editor.selection.clearSelection(); editor.setEmacsMark(null); + editor.keyBinding.$data.count = null; }, focusCommandLine: function(editor, arg) { if (editor.showCommandLine) diff --git a/lib/ace/keyboard/emacs_test.js b/lib/ace/keyboard/emacs_test.js index 09693156..3ba5efaa 100644 --- a/lib/ace/keyboard/emacs_test.js +++ b/lib/ace/keyboard/emacs_test.js @@ -76,9 +76,6 @@ module.exports = { assert.ok(editor.selection.isEmpty(), 'selection non-empty'); }, -// this.aceEditor.getSelectedText() -// this.aceEditor.selection.getAllRanges() -// lively.ide.ace.require("ace/range").Range.fromPoints(start, end) "test: exchangePointAndMark without mark set": function() { initEditor('foo'); sel.setRange(Range.fromPoints({row: 0, column: 1}, {row: 0, column: 3})); diff --git a/lib/ace/keyboard/keybinding.js b/lib/ace/keyboard/keybinding.js index c43d7930..cddf0666 100644 --- a/lib/ace/keyboard/keybinding.js +++ b/lib/ace/keyboard/keybinding.js @@ -89,8 +89,16 @@ var KeyBinding = function(editor) { this.getKeyboardHandler = function() { return this.$handlers[this.$handlers.length - 1]; }; + + this.getStatusText = function() { + var data = this.$data; + var editor = data.editor; + return this.$handlers.map(function(h) { + return h.getStatusText && h.getStatusText(editor, data) || ""; + }).filter(Boolean).join(" "); + }; - this.$callKeyboardHandlers = function (hashId, keyString, keyCode, e) { + this.$callKeyboardHandlers = function(hashId, keyString, keyCode, e) { var toExecute; var success = false; var commands = this.$editor.commands;