fixing multi selection handling for various emacs commands

Conflicts:
	lib/ace/keyboard/emacs.js
This commit is contained in:
Robert Krahn 2014-03-21 22:41:46 -07:00
commit 90034c3a44

View file

@ -318,7 +318,8 @@ exports.handler.handleKeyboard = function(data, hashId, key, keyCode) {
exec: function(editor, args) { exec: function(editor, args) {
for (var i = 0; i < count; i++) for (var i = 0; i < count; i++)
command.exec(editor, args); command.exec(editor, args);
} },
multiSelectAction: command.multiSelectAction
} }
}; };
} else { } else {
@ -439,37 +440,39 @@ exports.handler.addCommands({
// selection modification commands. That is, // selection modification commands. That is,
// "goto" commands become "select" commands. // "goto" commands become "select" commands.
// Any insertion or mouse click resets mark-mode. // Any insertion or mouse click resets mark-mode.
// setMark twice in a row at the same place resets markmode // setMark twice in a row at the same place resets markmode.
// in multi select mode, ea selection is handled individually
if (args && args.count) { if (args && args.count) {
var mark = editor.popEmacsMark(); function moveToMark() {
mark && editor.selection.moveCursorToPosition(mark); var mark = editor.popEmacsMark();
mark && editor.moveCursorToPosition(mark);
}
if (editor.inMultiSelectMode) editor.forEachSelection({exec: moveToMark});
else moveToMark();
return; return;
} }
var mark = editor.emacsMark(), var mark = editor.emacsMark(),
transientMarkModeActive = true; ranges = editor.selection.getAllRanges(),
rangePositions = ranges.map(function(r) { return {row: r.start.row, column: r.start.column}; }),
transientMarkModeActive = true,
hasNoSelection = ranges.every(function(range) { return range.isEmpty(); });
// if transientMarkModeActive then mark behavior is a little // if transientMarkModeActive then mark behavior is a little
// different. Deactivate the mark when setMark is run with active // different. Deactivate the mark when setMark is run with active
// mark // mark
if (transientMarkModeActive && (mark || !editor.selection.isEmpty())) { if (transientMarkModeActive && (mark || !hasNoSelection)) {
editor.pushEmacsMark(); if (editor.inMultiSelectMode) editor.forEachSelection({exec: editor.clearSelection.bind(editor)})
editor.clearSelection(); else editor.clearSelection();
if (mark) editor.pushEmacsMark(null);
return; return;
} }
if (mark) { if (!mark) {
var cp = editor.getCursorPosition(); rangePositions.slice(0,-1).forEach(function(pos) { editor.pushEmacsMark(pos); });
if (editor.selection.isEmpty() && editor.setEmacsMark(rangePositions[rangePositions.length-1]);
mark.row == cp.row && mark.column == cp.column) { return;
editor.pushEmacsMark();
return;
}
} }
// turn on mark mode
mark = editor.getCursorPosition();
editor.setEmacsMark(mark);
editor.selection.setSelectionAnchor(mark.row, mark.column);
}, },
readOnly: true, readOnly: true,
handlesCount: true, handlesCount: true,
@ -544,6 +547,7 @@ exports.handler.addCommands({
if (editor.keyBinding.$data.lastCommand != "yank") if (editor.keyBinding.$data.lastCommand != "yank")
return; return;
editor.undo(); editor.undo();
editor.session.$emacsMarkRing.pop(); // also undo recording mark
editor.onPaste(exports.killRing.rotate()); editor.onPaste(exports.killRing.rotate());
editor.keyBinding.$data.lastCommand = "yank"; editor.keyBinding.$data.lastCommand = "yank";
}, },
@ -557,12 +561,25 @@ exports.handler.addCommands({
}, },
killRingSave: { killRingSave: {
exec: function(editor) { exec: function(editor) {
// copy text and deselect. will save marks for starts of the
// selection(s)
editor.$handlesEmacsOnCopy = true;
var marks = editor.session.$emacsMarkRing.slice(),
deselectedMarks = [];
exports.killRing.add(editor.getCopyText()); exports.killRing.add(editor.getCopyText());
setTimeout(function() { setTimeout(function() {
var sel = editor.selection, function deselect() {
range = sel.getRange(); var sel = editor.selection, range = sel.getRange(),
editor.pushEmacsMark(sel.isBackwards() ? range.end : range.start); pos = sel.isBackwards() ? range.end : range.start;
sel.clearSelection(); deselectedMarks.push({row: pos.row, column: pos.column});
sel.clearSelection();
}
editor.$handlesEmacsOnCopy = false;
if (editor.inMultiSelectMode) editor.forEachSelection({exec: deselect});
else deselect();
editor.session.$emacsMarkRing = marks.concat(deselectedMarks.reverse());
}, 0); }, 0);
}, },
readOnly: true readOnly: true