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) {
for (var i = 0; i < count; i++)
command.exec(editor, args);
}
},
multiSelectAction: command.multiSelectAction
}
};
} else {
@ -439,37 +440,39 @@ exports.handler.addCommands({
// 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
// setMark twice in a row at the same place resets markmode.
// in multi select mode, ea selection is handled individually
if (args && args.count) {
var mark = editor.popEmacsMark();
mark && editor.selection.moveCursorToPosition(mark);
function moveToMark() {
var mark = editor.popEmacsMark();
mark && editor.moveCursorToPosition(mark);
}
if (editor.inMultiSelectMode) editor.forEachSelection({exec: moveToMark});
else moveToMark();
return;
}
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
// different. Deactivate the mark when setMark is run with active
// mark
if (transientMarkModeActive && (mark || !editor.selection.isEmpty())) {
editor.pushEmacsMark();
editor.clearSelection();
if (transientMarkModeActive && (mark || !hasNoSelection)) {
if (editor.inMultiSelectMode) editor.forEachSelection({exec: editor.clearSelection.bind(editor)})
else editor.clearSelection();
if (mark) editor.pushEmacsMark(null);
return;
}
if (mark) {
var cp = editor.getCursorPosition();
if (editor.selection.isEmpty() &&
mark.row == cp.row && mark.column == cp.column) {
editor.pushEmacsMark();
return;
}
if (!mark) {
rangePositions.slice(0,-1).forEach(function(pos) { editor.pushEmacsMark(pos); });
editor.setEmacsMark(rangePositions[rangePositions.length-1]);
return;
}
// turn on mark mode
mark = editor.getCursorPosition();
editor.setEmacsMark(mark);
editor.selection.setSelectionAnchor(mark.row, mark.column);
},
readOnly: true,
handlesCount: true,
@ -544,6 +547,7 @@ exports.handler.addCommands({
if (editor.keyBinding.$data.lastCommand != "yank")
return;
editor.undo();
editor.session.$emacsMarkRing.pop(); // also undo recording mark
editor.onPaste(exports.killRing.rotate());
editor.keyBinding.$data.lastCommand = "yank";
},
@ -557,12 +561,25 @@ exports.handler.addCommands({
},
killRingSave: {
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());
setTimeout(function() {
var sel = editor.selection,
range = sel.getRange();
editor.pushEmacsMark(sel.isBackwards() ? range.end : range.start);
sel.clearSelection();
function deselect() {
var sel = editor.selection, range = sel.getRange(),
pos = sel.isBackwards() ? range.end : range.start;
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);
},
readOnly: true