Skip to content

Commit ddd36cb

Browse files
binnymightyguava
authored andcommitted
[vim] visual block replace
1 parent 2fa988d commit ddd36cb

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

keymap/vim.js

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2370,30 +2370,41 @@
23702370
var curStart = cm.getCursor();
23712371
var replaceTo;
23722372
var curEnd;
2373-
if (vim.visualMode){
2374-
curStart=cm.getCursor('start');
2375-
curEnd=cm.getCursor('end');
2376-
}else{
2373+
var selections = cm.listSelections();
2374+
if (vim.visualMode) {
2375+
curStart = cm.getCursor('start');
2376+
curEnd = cm.getCursor('end');
2377+
} else {
23772378
var line = cm.getLine(curStart.line);
23782379
replaceTo = curStart.ch + actionArgs.repeat;
23792380
if (replaceTo > line.length) {
23802381
replaceTo=line.length;
23812382
}
23822383
curEnd = Pos(curStart.line, replaceTo);
23832384
}
2384-
if (replaceWith=='\n'){
2385+
if (replaceWith=='\n') {
23852386
if (!vim.visualMode) cm.replaceRange('', curStart, curEnd);
23862387
// special case, where vim help says to replace by just one line-break
23872388
(CodeMirror.commands.newlineAndIndentContinueComment || CodeMirror.commands.newlineAndIndent)(cm);
2388-
}else {
2389-
var replaceWithStr=cm.getRange(curStart, curEnd);
2389+
} else {
2390+
var replaceWithStr = cm.getRange(curStart, curEnd);
23902391
//replace all characters in range by selected, but keep linebreaks
2391-
replaceWithStr=replaceWithStr.replace(/[^\n]/g,replaceWith);
2392-
cm.replaceRange(replaceWithStr, curStart, curEnd);
2393-
if (vim.visualMode){
2392+
replaceWithStr = replaceWithStr.replace(/[^\n]/g, replaceWith);
2393+
if (vim.visualBlock) {
2394+
// Tabs are split in visua block before replacing
2395+
var spaces = new Array(cm.options.tabSize+1).join(' ');
2396+
replaceWithStr = cm.getSelection();
2397+
replaceWithStr = replaceWithStr.replace(/\t/g, spaces).replace(/[^\n]/g, replaceWith).split('\n');
2398+
cm.replaceSelections(replaceWithStr);
2399+
} else {
2400+
cm.replaceRange(replaceWithStr, curStart, curEnd);
2401+
}
2402+
if (vim.visualMode) {
2403+
curStart = cursorIsBefore(selections[0].anchor, selections[0].head) ?
2404+
selections[0].anchor : selections[0].head;
23942405
cm.setCursor(curStart);
23952406
exitVisualMode(cm);
2396-
}else{
2407+
} else {
23972408
cm.setCursor(offsetCursor(curEnd, 0, -1));
23982409
}
23992410
}

test/vim_test.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,19 @@ testVim('r', function(cm, vim, helpers) {
13321332
helpers.doKeys('v', 'j', 'h', 'r', '<Space>');
13331333
eq('wuuu \n her', cm.getValue(),'Replacing selection by space-characters failed');
13341334
}, { value: 'wordet\nanother' });
1335+
testVim('r_visual_block', function(cm, vim, helpers) {
1336+
cm.setCursor(2, 3);
1337+
helpers.doKeys('<C-v>', 'k', 'k', 'h', 'h', 'r', 'l');
1338+
eq('1lll\n5lll\nalllefg', cm.getValue());
1339+
helpers.doKeys('<C-v>', 'l', 'j', 'r', '<Space>');
1340+
eq('1 l\n5 l\nalllefg', cm.getValue());
1341+
cm.setCursor(2, 0);
1342+
helpers.doKeys('o');
1343+
helpers.doInsertModeKeys('Esc');
1344+
cm.replaceRange('\t\t', cm.getCursor());
1345+
helpers.doKeys('<C-v>', 'h', 'h', 'r', 'r');
1346+
eq('1 l\n5 l\nalllefg\nrrrrrrrr', cm.getValue());
1347+
}, {value: '1234\n5678\nabcdefg'});
13351348
testVim('R', function(cm, vim, helpers) {
13361349
cm.setCursor(0, 1);
13371350
helpers.doKeys('R');

0 commit comments

Comments
 (0)