emacs: use mark ring instead of single mark

This commit is contained in:
Robert Krahn 2013-05-26 21:01:33 -07:00
commit 6b01dde666

View file

@ -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)