From a7cccae0393cefd52b72f115e2007e5b0e61d922 Mon Sep 17 00:00:00 2001 From: Robert Krahn Date: Sun, 26 May 2013 17:14:06 -0700 Subject: [PATCH] fixing emacs multiselect cut/copy/paste --- lib/ace/keyboard/emacs.js | 74 +++++++++++++++++++++++---------------- lib/ace/multi_select.js | 6 ++-- 2 files changed, 46 insertions(+), 34 deletions(-) diff --git a/lib/ace/keyboard/emacs.js b/lib/ace/keyboard/emacs.js index 87423711..136ec81b 100644 --- a/lib/ace/keyboard/emacs.js +++ b/lib/ace/keyboard/emacs.js @@ -367,28 +367,32 @@ exports.handler.addCommands({ selectRectangularRegion: function(editor) { editor.multiSelect.toggleBlockSelection(); }, - setMark: function(editor) { - // Emulate emacs highlighting behaviour in transient-mark-mode. - // Sets mark-mode and clears current selection. - // When mark is set, keyboard cursor movement commands become - // selection modification commands. That is, - // "goto" commands become "select" commands. - // Any insertion or mouse click resets mark-mode. - // setMark twice in a row at the same place resets markmode - var markMode = editor.emacsMarkMode(); - if (markMode) { - var cp = editor.getCursorPosition(); - if (editor.selection.isEmpty() && - markMode.row == cp.row && markMode.column == cp.column) { - editor.setEmacsMarkMode(null); - // console.log("Mark mode off"); - return; + setMark: { + exec: function(editor) { + // Emulate emacs highlighting behaviour in transient-mark-mode. + // Sets mark-mode and clears current selection. + // When mark is set, keyboard cursor movement commands become + // selection modification commands. That is, + // "goto" commands become "select" commands. + // Any insertion or mouse click resets mark-mode. + // setMark twice in a row at the same place resets markmode + var markMode = editor.emacsMarkMode(); + if (markMode) { + var cp = editor.getCursorPosition(); + if (editor.selection.isEmpty() && + markMode.row == cp.row && markMode.column == cp.column) { + editor.setEmacsMarkMode(null); + // console.log("Mark mode off"); + return; + } } - } - // turn on mark mode - markMode = editor.getCursorPosition(); - editor.setEmacsMarkMode(markMode); - editor.selection.setSelectionAnchor(markMode.row, markMode.column); + // turn on mark mode + markMode = editor.getCursorPosition(); + editor.setEmacsMarkMode(markMode); + editor.selection.setSelectionAnchor(markMode.row, markMode.column); + }, + readonly: true, + multiSelectAction: "forEach" }, exchangePointAndMark: { exec: function(editor) { @@ -396,7 +400,7 @@ exports.handler.addCommands({ editor.selection.setSelectionRange(range, !editor.selection.isBackwards()); }, readonly: true, - multiselectAction: "forEach" + multiSelectAction: "forEach" }, killWord: { exec: function(editor, dir) { @@ -413,7 +417,7 @@ exports.handler.addCommands({ editor.session.remove(range); editor.clearSelection(); }, - multiselectAction: "forEach" + multiSelectAction: "forEach" }, killLine: function(editor) { editor.setEmacsMarkMode(null); @@ -438,7 +442,7 @@ exports.handler.addCommands({ editor.clearSelection(); }, yank: function(editor) { - editor.onPaste(exports.killRing.get()); + editor.onPaste(exports.killRing.get() || ''); editor.keyBinding.$data.lastCommand = "yank"; }, yankRotate: function(editor) { @@ -448,12 +452,19 @@ exports.handler.addCommands({ editor.onPaste(exports.killRing.rotate()); editor.keyBinding.$data.lastCommand = "yank"; }, - killRegion: function(editor) { - exports.killRing.add(editor.getCopyText()); - editor.commands.byName.cut.exec(editor); + killRegion: { + exec: function(editor) { + exports.killRing.add(editor.getCopyText()); + editor.commands.byName.cut.exec(editor); + }, + readonly: true, + multiSelectAction: "forEach" }, - killRingSave: function(editor) { - exports.killRing.add(editor.getCopyText()); + killRingSave: { + exec: function(editor) { + exports.killRing.add(editor.getCopyText()); + }, + readonly: true }, keyboardQuit: function(editor) { editor.selection.clearSelection(); @@ -478,8 +489,9 @@ exports.killRing = { if (this.$data.length > 30) this.$data.shift(); }, - get: function() { - return this.$data[this.$data.length - 1] || ""; + get: function(n) { + n = n || 1; + return this.$data.slice(this.$data.length-n, this.$data.length).reverse().join('\n'); }, pop: function() { if (this.$data.length > 1) diff --git a/lib/ace/multi_select.js b/lib/ace/multi_select.js index d00bfb05..86fc5475 100644 --- a/lib/ace/multi_select.js +++ b/lib/ace/multi_select.js @@ -521,7 +521,7 @@ var Editor = require("./editor").Editor; this.getCopyText = function() { var text = ""; - if (this.inMultiSelectMode) { + if (this.inMultiSelectMode && !this.inVirtualSelectionMode) { var ranges = this.multiSelect.rangeList.ranges; var buf = []; for (var i = 0; i < ranges.length; i++) { @@ -550,10 +550,10 @@ var Editor = require("./editor").Editor; var lines = text.split(/\r\n|\r|\n/); var ranges = this.selection.rangeList.ranges; - if (lines.length > ranges.length || (lines.length <= 2 && !lines[1])) + if (lines.length > ranges.length || lines.length < 2 || !lines[1]) return this.commands.exec("insertstring", this, text); - for (var i = ranges.length; i--; ) { + for (var i = ranges.length; i--;) { var range = ranges[i]; if (!range.isEmpty()) this.session.remove(range);