Skip to content

Commit 5708251

Browse files
nightwingmarijnh
authored andcommitted
[vim] fix insert mode repeat after visualBlock edits
1 parent 6ec64f5 commit 5708251

2 files changed

Lines changed: 13 additions & 29 deletions

File tree

keymap/vim.js

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5079,32 +5079,7 @@
50795079
var insertModeChangeRegister = vimGlobalState.registerController.getRegister('.');
50805080
var isPlaying = macroModeState.isPlaying;
50815081
var lastChange = macroModeState.lastInsertModeChanges;
5082-
// In case of visual block, the insertModeChanges are not saved as a
5083-
// single word, so we convert them to a single word
5084-
// so as to update the ". register as expected in real vim.
5085-
var text = [];
50865082
if (!isPlaying) {
5087-
var selLength = lastChange.inVisualBlock && vim.lastSelection ?
5088-
vim.lastSelection.visualBlock.height : 1;
5089-
var changes = lastChange.changes;
5090-
var text = [];
5091-
var i = 0;
5092-
// In case of multiple selections in blockwise visual,
5093-
// the inserted text, for example: 'f<Backspace>oo', is stored as
5094-
// 'f', 'f', InsertModeKey 'o', 'o', 'o', 'o'. (if you have a block with 2 lines).
5095-
// We push the contents of the changes array as per the following:
5096-
// 1. In case of InsertModeKey, just increment by 1.
5097-
// 2. In case of a character, jump by selLength (2 in the example).
5098-
while (i < changes.length) {
5099-
// This loop will convert 'ff<bs>oooo' to 'f<bs>oo'.
5100-
text.push(changes[i]);
5101-
if (changes[i] instanceof InsertModeKey) {
5102-
i++;
5103-
} else {
5104-
i+= selLength;
5105-
}
5106-
}
5107-
lastChange.changes = text;
51085083
cm.off('change', onChange);
51095084
CodeMirror.off(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown);
51105085
}
@@ -5235,17 +5210,24 @@
52355210
if (!macroModeState.isPlaying) {
52365211
while(changeObj) {
52375212
lastChange.expectCursorActivityForChange = true;
5238-
if (changeObj.origin == '+input' || changeObj.origin == 'paste'
5213+
if (lastChange.ignoreCount > 1) {
5214+
lastChange.ignoreCount--;
5215+
} else if (changeObj.origin == '+input' || changeObj.origin == 'paste'
52395216
|| changeObj.origin === undefined /* only in testing */) {
5217+
var selectionCount = cm.listSelections().length;
5218+
if (selectionCount > 1)
5219+
lastChange.ignoreCount = selectionCount;
52405220
var text = changeObj.text.join('\n');
52415221
if (lastChange.maybeReset) {
52425222
lastChange.changes = [];
52435223
lastChange.maybeReset = false;
52445224
}
5245-
if (cm.state.overwrite && !/\n/.test(text)) {
5225+
if (text) {
5226+
if (cm.state.overwrite && !/\n/.test(text)) {
52465227
lastChange.changes.push([text]);
5247-
} else {
5228+
} else {
52485229
lastChange.changes.push(text);
5230+
}
52495231
}
52505232
}
52515233
// Change objects may be chained with next.

test/vim_test.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4231,7 +4231,9 @@ testVim('ex_imap', function(cm, vim, helpers) {
42314231
cm.setCursor(0, 1);
42324232
CodeMirror.Vim.map('jj', '<Esc>', 'insert');
42334233
helpers.doKeys('<C-v>', '2', 'j', 'l', 'c');
4234-
var replacement = fillArray('fo', 3);
4234+
var replacement = fillArray('f', 3);
4235+
cm.replaceSelections(replacement);
4236+
var replacement = fillArray('o', 3);
42354237
cm.replaceSelections(replacement);
42364238
eq('1fo4\n5fo8\nafodefg', cm.getValue());
42374239
helpers.doKeys('j', 'j');

0 commit comments

Comments
 (0)