fixing multi selection handling for various emacs commands
Conflicts: lib/ace/keyboard/emacs.js
This commit is contained in:
parent
f133231df8
commit
90034c3a44
1 changed files with 41 additions and 24 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue