emacs: use mark ring instead of single mark
This commit is contained in:
parent
353958b98c
commit
6b01dde666
1 changed files with 37 additions and 23 deletions
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue