diff --git a/lib/ace/keyboard/emacs.js b/lib/ace/keyboard/emacs.js index b0ef90ca..4d3dfb7b 100644 --- a/lib/ace/keyboard/emacs.js +++ b/lib/ace/keyboard/emacs.js @@ -51,17 +51,6 @@ exports.handler = new HashHandler(); var initialized = false; -// When mark is set, keyboard cursor movement commands become selection -// modification commands. This is a little different than emacs. In -// emacs, keyboard cursor movement always sets mark, but it does not -// highlight the region unless mark has been otherwise explicitly set -// and transient-mark-mode is on. -// In ACE, there is no concept of a region that is not highlighted, -// so we just work with highlighted area === region. It would probably be -// confusing to most users anyway if a cut command, say, were to delete an -// area that was not highlighted. -var markMode; - exports.handler.attach = function(editor) { if (!initialized) { initialized = true; @@ -95,7 +84,13 @@ exports.handler.attach = function(editor) { // in emacs, gotowordleft/right should not count a space as a word.. editor.session.$selectLongWords = true; - markMode = false; + exports.markMode = function() { + return editor.session.$emacsMark; + } + + exports.setMarkMode = function(p) { + editor.session.$emacsMark = p; + } editor.on("click",$resetMarkMode); @@ -103,6 +98,9 @@ exports.handler.attach = function(editor) { // kitchen sink seems to reload the session after loading the kb handler. editor.on("changeSession",function(e) { e.session.$selectLongWords = true; + if (! e.session.hasOwnProperty('$emacsMark')) { + e.session.$emacsMark = false; + } }); editor.renderer.screenToTextCoordinates = screenToTextBlockCoordinates; @@ -121,7 +119,7 @@ exports.handler.detach = function(editor) { }; var $resetMarkMode = function(e) { - markMode = null; + e.editor.session.$emacsMark = null; } var keys = require("../lib/keys").KEY_MODS; @@ -153,7 +151,7 @@ exports.handler.bindKey = function(key, command) { exports.handler.handleKeyboard = function(data, hashId, key, keyCode) { if (hashId == -1) { - markMode = null; + exports.setMarkMode(null); if (data.count) { var str = Array(data.count + 1).join(key); data.count = null; @@ -199,7 +197,7 @@ exports.handler.handleKeyboard = function(data, hashId, key, keyCode) { command = command.command; if (command == "goorselect") { command = args[0]; - if (markMode) { + if (exports.markMode()) { command = args[1]; } args = null; @@ -210,7 +208,7 @@ exports.handler.handleKeyboard = function(data, hashId, key, keyCode) { if (command == "insertstring" || command == "splitline" || command == "togglecomment") { - markMode = null; + exports.setMarkMode(null); } command = this.commands[command] || data.editor.commands.commands[command]; } @@ -336,25 +334,29 @@ exports.handler.addCommands({ editor.multiSelect.toggleBlockSelection(); }, setMark: function(editor) { + // Emulate emacs highlighting behaviour in transient-mark-mode. // Sets mark-mode and clears current selection. - // When in mark-mode, "goto" commands become "select" commands. + // 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 = exports.markMode(); if (markMode) { cp = editor.getCursorPosition(); if (editor.selection.isEmpty() && markMode.row == cp.row && markMode.column == cp.column) { - // setMark twice in a row at the same place - // resets markmode - markMode = null; - console.log("Mark mode off"); + exports.setMarkMode(null); + // console.log("Mark mode off"); return; } } // turn on mark mode markMode = editor.getCursorPosition(); + exports.setMarkMode(markMode); editor.selection.setSelectionAnchor(markMode.row, markMode.column); }, @@ -385,7 +387,7 @@ exports.handler.addCommands({ multiselectAction: "forEach" }, killLine: function(editor) { - markMode = null; + exports.setMarkMode(null); var pos = editor.getCursorPosition(); if (pos.column == 0 &&