diff --git a/lib/ace/keyboard/emacs.js b/lib/ace/keyboard/emacs.js index 25f22a52..9bb30f6b 100644 --- a/lib/ace/keyboard/emacs.js +++ b/lib/ace/keyboard/emacs.js @@ -95,17 +95,15 @@ exports.handler.attach = function(editor) { $formerLineStart = editor.session.$useEmacsStyleLineStart; editor.session.$useEmacsStyleLineStart = true; - editor.session.$emacsMark = null; + editor.session.$emacsMark = null; // the active mark editor.session.$emacsMarkRing = editor.session.$emacsMarkRing || []; - editor.emacsMarkMode = function() { + editor.emacsMark = function() { return this.session.$emacsMark; } - editor.setEmacsMarkMode = function(p) { - var prevMark = this.session.$emacsMark; - if (prevMark) - this.session.$emacsMarkRing.push(prevMark); + editor.setEmacsMark = function(p) { + // to deactivate pass in a falsy value this.session.$emacsMark = p; } @@ -113,12 +111,18 @@ exports.handler.attach = function(editor) { var prevMark = this.session.$emacsMark; if (prevMark) this.session.$emacsMarkRing.push(prevMark); - if (activate) this.session.$emacsMark = p; + if (!p || activate) this.setEmacsMark(p) else this.session.$emacsMarkRing.push(p); } + editor.popEmacsMark = function() { + var mark = this.emacsMark(); + if (mark) { this.setEmacsMark(null); return mark; } + return this.session.$emacsMarkRing.pop(); + } + editor.getLastEmacsMark = function(p) { - return this.session.$emacsMark || this.session.$emacsMarkRing.reverse()[0]; + return this.session.$emacsMark || this.session.$emacsMarkRing.slice(-1)[0]; } editor.on("click", $resetMarkMode); @@ -209,7 +213,7 @@ exports.handler.handleKeyboard = function(data, hashId, key, keyCode) { var editor = data.editor; // insertstring data.count times if (hashId == -1) { - editor.setEmacsMarkMode(null); + editor.pushEmacsMark(); if (data.count) { var str = Array(data.count + 1).join(key); data.count = null; @@ -263,7 +267,7 @@ exports.handler.handleKeyboard = function(data, hashId, key, keyCode) { args = command.args; if (command.command) command = command.command; if (command === "goorselect") { - command = editor.emacsMarkMode() ? args[1] : args[0]; + command = editor.emacsMark() ? args[1] : args[0]; args = null; } } @@ -272,7 +276,7 @@ exports.handler.handleKeyboard = function(data, hashId, key, keyCode) { if (command === "insertstring" || command === "splitline" || command === "togglecomment") { - editor.setEmacsMarkMode(null); + editor.pushEmacsMark(); } command = this.commands[command] || editor.commands.commands[command]; if (!command) return undefined; @@ -401,28 +405,38 @@ exports.handler.addCommands({ editor.multiSelect.toggleBlockSelection(); }, setMark: { - exec: function(editor) { - // Emulate emacs highlighting behaviour in transient-mark-mode. + exec: function(editor, args) { // 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 mark = editor.emacsMark(), + transientMarkModeActive = true; + + // if transientMarkModeActive then mark behavior is a little + // different. Deactivate the mark when setMark is run with active + // mark + if (transientMarkModeActive && (mark || !editor.selection.isEmpty())) { + editor.pushEmacsMark(editor.getCursorPosition()); + editor.pushEmacsMark(); + editor.clearSelection(); + return; + } + + if (mark) { var cp = editor.getCursorPosition(); if (editor.selection.isEmpty() && - markMode.row == cp.row && markMode.column == cp.column) { - editor.setEmacsMarkMode(null); - // console.log("Mark mode off"); + mark.row == cp.row && mark.column == cp.column) { + editor.pushEmacsMark(); return; } } // turn on mark mode - markMode = editor.getCursorPosition(); - editor.setEmacsMarkMode(markMode); - editor.selection.setSelectionAnchor(markMode.row, markMode.column); + mark = editor.getCursorPosition(); + editor.setEmacsMark(mark); + editor.selection.setSelectionAnchor(mark.row, mark.column); }, readonly: true, multiSelectAction: "forEach" @@ -459,7 +473,7 @@ exports.handler.addCommands({ multiSelectAction: "forEach" }, killLine: function(editor) { - editor.setEmacsMarkMode(null); + editor.pushEmacsMark(null); var pos = editor.getCursorPosition(); if (pos.column == 0 && editor.session.doc.getLine(pos.row).length == 0) { @@ -513,7 +527,7 @@ exports.handler.addCommands({ }, keyboardQuit: function(editor) { editor.selection.clearSelection(); - editor.setEmacsMarkMode(null); + editor.setEmacsMark(null); }, focusCommandLine: function(editor, arg) { if (editor.showCommandLine)