Permalink
Browse files

Fix operator/line motion combinations.

  • Loading branch information...
1 parent c7e1d84 commit fb72e77266d12f0923549011c5ab59c44f244263 @georgebrock georgebrock committed Dec 7, 2012
Showing with 74 additions and 18 deletions.
  1. +28 −17 js/normal_mode/operators.js
  2. +1 −1 js/operation.js
  3. +21 −0 tests/acceptance/change.js
  4. +24 −0 tests/acceptance/delete.js
@@ -34,8 +34,9 @@
'd': new C({
repeatable: true,
argument: "operation",
+ defaultCount: null,
callback: function (vim, count, motion) {
- var before, after, range;
+ var before, after, range, firstRow, lastRow;
before = {row: vim.cursor.row, col: vim.cursor.col};
range = motion.execute(vim, count);
@@ -58,13 +59,18 @@
after.col += 1;
}
- // d, j and k delete whole rows
- if (/[dj]/.test(motion.commandKey)) {
- vim.removeRows(before.row, after.row + 1);
- vim.moveCursor(before.row, '^');
- } else if (/[k]/.test(motion.commandKey)) {
- vim.removeRows(after.row, before.row + 1);
- vim.moveCursor(after.row, '^');
+ // d, G, gg, j and k delete whole rows
+ if (/[djkG]|gg/.test(motion.commandKey)) {
+ if (before.row < after.row) {
+ firstRow = before.row;
+ lastRow = after.row + 1;
+ } else {
+ firstRow = after.row;
+ lastRow = before.row + 1;
+ }
+
+ vim.removeRows(firstRow, lastRow);
+ vim.moveCursor(lastRow, '^');
} else {
vim.removeRange(before, after);
}
@@ -88,8 +94,9 @@
'c': new C({
repeatable: true,
argument: "operation",
+ defaultCount: null,
callback: function (vim, count, motion) {
- var before, after, range;
+ var before, after, range, firstRow, lastRow;
before = {row: vim.cursor.row, col: vim.cursor.col};
range = motion.execute(vim, count);
@@ -113,14 +120,18 @@
}
// c, j and k change whole rows
- if (/[cj]/.test(motion.commandKey)) {
- vim.removeRows(before.row + 1, after.row + 1);
- vim.replaceRow('', before.row);
- vim.moveCursor(before.row, 0);
- } else if (/[k]/.test(motion.commandKey)) {
- vim.removeRows(after.row + 1, before.row + 1);
- vim.replaceRow('', after.row);
- vim.moveCursor(after.row, 0);
+ if (/[cjkG]|gg/.test(motion.commandKey)) {
+ if (before.row < after.row) {
+ firstRow = before.row;
+ lastRow = after.row + 1;
+ } else {
+ firstRow = after.row;
+ lastRow = before.row + 1;
+ }
+
+ vim.removeRows(firstRow + 1, lastRow);
+ vim.replaceRow('', firstRow);
+ vim.moveCursor(firstRow, 0);
} else {
vim.removeRange(before, after);
if (before.row > after.row || before.row == after.row && before.col > after.col) {
View
@@ -40,7 +40,7 @@
) {
this.multiplier = ~~('' + (this.multiplier || '') + key);
return;
- } else if (!this.commandPrefix && /[gz]/.test(key)) {
+ } else if (!this.command && !this.commandPrefix && /[gz]/.test(key)) {
// g and z are special: They are prefixes to other commands rather
// than being commands in their own right.
this.commandPrefix = key;
View
@@ -191,4 +191,25 @@ describe("The change operator c", function () {
expect(currentText()).toBe("One row");
});
});
+
+ describe("with line motions", function () {
+ beforeEach(function () {
+ reset("First\nSecond\nThird\nFourth");
+ });
+
+ it("changes to the end of the file with G", function () {
+ pressKeys("jlcG" + "Last" + ESC);
+ expect(currentText()).toBe("First\nLast");
+ });
+
+ it("changes to the beginning of the file with gg", function () {
+ pressKeys("Gkcgg" + "1st, 2nd, 3rd" + ESC);
+ expect(currentText()).toBe("1st, 2nd, 3rd\nFourth");
+ });
+
+ it("changes to a specific line with [count]G", function () {
+ pressKeys("jc3G" + "2 and 3" + ESC);
+ expect(currentText()).toBe("First\n2 and 3\nFourth");
+ });
+ });
});
View
@@ -180,4 +180,28 @@ describe("The delete operator d", function () {
expect(currentText()).toBe("ne row");
});
});
+
+ describe("with line motions", function () {
+ beforeEach(function () {
+ reset("First\nSecond\nThird\nFourth");
+ });
+
+ it("deletes to the end of the file with G", function () {
+ pressKeys("jldG");
+ expect(currentText()).toBe("First");
+ expect(cursorPosition()).toEqual({row: 0, col: 0});
+ });
+
+ it("deletes to the beginning of the file with gg", function () {
+ pressKeys("Gkdgg");
+ expect(currentText()).toBe("Fourth");
+ expect(cursorPosition()).toEqual({row: 0, col: 0});
+ });
+
+ it("deletes to a specific line with [count]G", function () {
+ pressKeys("jd3G");
+ expect(currentText()).toBe("First\nFourth");
+ expect(cursorPosition()).toEqual({row: 1, col: 0});
+ });
+ });
});

0 comments on commit fb72e77

Please sign in to comment.