Skip to content

Commit

Permalink
Refine and add tests for selection-related deletion commands
Browse files Browse the repository at this point in the history
Issue #778
  • Loading branch information
marijnh committed Nov 13, 2013
1 parent 1dd51b9 commit 08660b1
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 28 deletions.
72 changes: 44 additions & 28 deletions lib/codemirror.js
Original file line number Diff line number Diff line change
Expand Up @@ -2913,6 +2913,25 @@ window.CodeMirror = (function() {
return line;
}

function deleteNearSelection(cm, compute) {
var ranges = cm.doc.sel.ranges, kill = [];
for (var i = 0; i < ranges.length; i++) {
var toKill = compute(ranges[i]);
while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {
var replaced = kill.pop();
if (cmp(replaced.from, toKill.from) < 0) {
toKill.from = replaced.from;
break;
}
}
kill.push(toKill);
}
cm.operation(function() {
for (var i = kill.length - 1; i >= 0; i--)
replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete");
});
}

function findPosH(doc, pos, dir, unit, visually) {
var line = pos.line, ch = pos.ch, origDir = dir;
var lineObj = getLine(doc, line);
Expand Down Expand Up @@ -3276,7 +3295,7 @@ window.CodeMirror = (function() {
var sel = this.doc.sel, pos = [];
for (var i = 0; i < sel.ranges.length; i++) {
var range = sel.ranges[i];
if (this.shift || this.doc.extend || range.empty())
if (this.display.shift || this.doc.extend || range.empty())
pos[i] = findPosH(this.doc, range.head, dir, unit, this.options.rtlMoveVisually);
else
pos[i] = dir < 0 ? range.from() : range.to();
Expand All @@ -3285,15 +3304,14 @@ window.CodeMirror = (function() {
}),

deleteH: operation(null, function(dir, unit) {
var sel = this.doc.sel;
if (sel.somethingSelected()) {
this.doc.replaceSelection("", null, "+delete");
} else {
for (var i = sel.ranges.length - 1; i >= 0; i--) {
var range = sel.ranges[i];
replaceRange(this.doc, "", range.head, findPosH(this.doc, range.head, dir, unit, false), "+delete");
}
}
var sel = this.doc.sel, doc = this.doc;
if (sel.somethingSelected())
doc.replaceSelection("", null, "+delete");
else
deleteNearSelection(this, function(range) {
var other = findPosH(doc, range.head, dir, unit, false);
return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other};
});
this.curOp.userSelChange = true;
}),

Expand Down Expand Up @@ -3624,30 +3642,28 @@ window.CodeMirror = (function() {
var commands = CodeMirror.commands = {
selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()));},
killLine: function(cm) {
var ranges = cm.listSelections(), kill = [];
for (var i = 0; i < ranges.length; i++) {
var r = ranges[i], from = r.from(), to = r.to();
if (r.empty()) {
var len = cm.getLine(to.line).length;
if (to.ch == len) to = Pos(to.line + 1, 0);
else to = Pos(to.line, len);
if (i < ranges.length - 1 && cmp(to, ranges[i + 1].from()) > 0)
to = ranges[i + 1].from();
deleteNearSelection(cm, function(range) {
if (range.empty()) {
var len = getLine(cm.doc, range.head.line).text.length;
if (range.head.ch == len && range.head.line < cm.lastLine())
return {from: range.head, to: Pos(range.head.line + 1, 0)};
else
return {from: range.head, to: Pos(range.head.line, len)};
} else {
return {from: range.from(), to: range.to()};
}
kill.push(from, to);
}
cm.operation(function() {
for (var i = kill.length - 2; i >= 0; i -= 2)
cm.replaceRange("", kill[i], kill[i + 1], "+delete");
});
},
deleteLine: function(cm) {
var l = cm.getCursor().line;
cm.replaceRange("", Pos(l, 0), Pos(l), "+delete");
deleteNearSelection(cm, function(range) {
return {from: Pos(range.from().line, 0),
to: clipPos(cm.doc, Pos(range.to().line + 1, 0))};
});
},
delLineLeft: function(cm) {
var cur = cm.getCursor();
cm.replaceRange("", Pos(cur.line, 0), cur, "+delete");
deleteNearSelection(cm, function(range) {
return {from: Pos(range.from().line, 0), to: range.from()};
});
},
undo: function(cm) {cm.undo();},
redo: function(cm) {cm.redo();},
Expand Down
25 changes: 25 additions & 0 deletions test/multi_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,29 @@
cm.execCommand("killLine");
eq(cm.getValue(), "faz");
}, {value: "foo\nbar\nbaz"});

testCM("deleteLine", function(cm) {
select(cm, Pos(0, 0),
{head: Pos(0, 1), anchor: Pos(2, 0)},
Pos(4, 0));
cm.execCommand("deleteLine");
eq(cm.getValue(), "4\n6\n7");
select(cm, Pos(2, 1));
cm.execCommand("deleteLine");
eq(cm.getValue(), "4\n6\n");
}, {value: "1\n2\n3\n4\n5\n6\n7"});

testCM("deleteH", function(cm) {
select(cm, Pos(0, 4), {anchor: Pos(1, 4), head: Pos(1, 5)});
cm.execCommand("delWordAfter");
eq(cm.getValue(), "foo bar baz\nabc ef ghi\n");
cm.execCommand("delWordAfter");
eq(cm.getValue(), "foo baz\nabc ghi\n");
cm.execCommand("delCharBefore");
cm.execCommand("delCharBefore");
eq(cm.getValue(), "fo baz\nab ghi\n");
select(cm, Pos(0, 3), Pos(0, 4), Pos(0, 5));
cm.execCommand("delWordAfter");
eq(cm.getValue(), "fo \nab ghi\n");
}, {value: "foo bar baz\nabc def ghi\n"});
})();

0 comments on commit 08660b1

Please sign in to comment.