Skip to content

Commit d190ea8

Browse files
authored
fix visual block indent (#222)
1 parent e2035e4 commit d190ea8

File tree

3 files changed

+43
-5
lines changed

3 files changed

+43
-5
lines changed

src/vim.js

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2791,8 +2791,40 @@ export function initVim(CM) {
27912791
},
27922792
indent: function(cm, args, ranges) {
27932793
var vim = cm.state.vim;
2794-
var repeat = (vim.visualMode) ? (args.repeat || 0) : 1;
2795-
if (cm.indentMore) {
2794+
// In visual mode, n> shifts the selection right n times, instead of
2795+
// shifting n lines right once.
2796+
var repeat = vim.visualMode ? args.repeat || 1 : 1;
2797+
if (vim.visualBlock) {
2798+
var tabSize = cm.getOption('tabSize');
2799+
var indent = cm.getOption('indentWithTabs') ? '\t' : ' '.repeat(tabSize);
2800+
var cursor;
2801+
for (var i = ranges.length - 1; i >= 0; i--) {
2802+
cursor = cursorMin(ranges[i].anchor, ranges[i].head);
2803+
if (args.indentRight) {
2804+
cm.replaceRange(indent.repeat(repeat), cursor, cursor);
2805+
} else {
2806+
var text = cm.getLine(cursor.line);
2807+
var end = 0;
2808+
for (var j = 0; j < repeat; j++) {
2809+
var ch = text[cursor.ch + end];
2810+
if (ch == '\t') {
2811+
end++;
2812+
} else if (ch == ' ') {
2813+
end++;
2814+
for (var k = 1; k < indent.length; k++) {
2815+
ch = text[cursor.ch + end];
2816+
if (ch !== ' ') break;
2817+
end++;
2818+
}
2819+
} else {
2820+
break
2821+
}
2822+
}
2823+
cm.replaceRange('', cursor, offsetCursor(cursor, 0, end));
2824+
}
2825+
}
2826+
return cursor;
2827+
} else if (cm.indentMore) {
27962828
for (var j = 0; j < repeat; j++) {
27972829
if (args.indentRight) cm.indentMore();
27982830
else cm.indentLess();
@@ -2802,8 +2834,6 @@ export function initVim(CM) {
28022834
var endLine = vim.visualBlock ?
28032835
ranges[ranges.length - 1].anchor.line :
28042836
ranges[0].head.line;
2805-
// In visual mode, n> shifts the selection right n times, instead of
2806-
// shifting n lines right once.
28072837
if (args.linewise) {
28082838
// The only way to delete a newline is to delete until the start of
28092839
// the next line, so in linewise mode evalInput will include the next

test/vim_test.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,6 +1508,14 @@ testVim('=', function(cm, vim, helpers) {
15081508
helpers.doKeys('=');
15091509
eq(expectedValue, cm.getValue());
15101510
}, { value: ' word1\n word2\n word3', indentUnit: 2 });
1511+
testVim('><visualblock', function(cm, vim, helpers) {
1512+
cm.setCursor(0, 6);
1513+
helpers.doKeys('<C-v>', 'j', 'j');
1514+
helpers.doKeys('4', '>');
1515+
eq(' word 1\n word 2\n word 3', cm.getValue());
1516+
helpers.doKeys('g', 'v', '14', '<');
1517+
eq(' word1\n word2\n word3', cm.getValue());
1518+
}, { value: ' word1\n word2\n word3', indentUnit: 2 });
15111519

15121520

15131521
// Edit tests

test/webtest-vim.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ describe("Vim extension", () => {
4949
vim({}),
5050
basicSetup,
5151
options.mode == "xml" ? xml() : javascript(),
52-
EditorState.tabSize.of(options.tabSize || 4),
52+
EditorState.tabSize.of(options.tabSize || options.indentUnit || 4),
5353
indentUnit.of(
5454
options.indentWithTabs ? "\t" : " ".repeat(options.indentUnit || 2)
5555
),

0 commit comments

Comments
 (0)