Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Vim's normal mode CTRL-A number increment in visual block mode?

Tags:

vim

I have a table:

0 | 3
1 | 4
2 | 5

In normal mode, I can go over 0, hit CTRL-A and it becomes 1.

I want something analogous for visual block mode (in which CTRL-A does not increment the selection), to use it on the second column and obtain:

0 | 4
1 | 5
2 | 6

Is that possible without a macro / plugin / defining a function?

Best simple workaround so far was defining a macro, counting columns, and repeating it the right number of times, but I keep thinking: why is there no CTRL-A for visual block?

My initial example was:

a | 3
b | 4
c | 5

For that particular case in which the number is the first numeric row of the table, the answer given by @hawk and @romainl worked well: :norm! ^A, which expands to :'<,'>norm! ^A. Is there a way to take care of the general case?


3 Answers

This has been added in version 8. Check out :help new-items-8

Edit: Changed the help command above.

Result of :help new-items-8

Visual mode commands:
v_CTRL-A        CTRL-A          add N to number in highlighted text
v_CTRL-X        CTRL-X          subtract N from number in highlighted text
v_g_CTRL-A      g CTRL-A        add N to number in highlighted text
v_g_CTRL-X      g CTRL-X        subtract N from number in highlighted text
like image 131
Ankit Jain Avatar answered Oct 15 '22 19:10

Ankit Jain


I doubt anyone here will be able to tell you exactly why there's no <C-a> for visual block mode.

The best we can do is help you find an efficient way to achieve your goal.

Plugins like VisIncr by DrChip or speeddating by Tim Pope are specifically designed to address that "missing feature".

If your needs are relatively simple, like in your example, a simple :norm <C-v><C-a> could be enough. Maybe with a mapping…

xnoremap <C-a> :normal! ^A

(The ^A is obtained with <C-v><C-a>.)

(edit)

A more generic approach exists but it is not very finger-friendly:

:'<,'>s/\%V\d\+/\=submatch(0) + 1/g

You could map it, of course, and make it a little smarter:

xnoremap <C-a> :<C-u>let vcount = v:count ? v:count : 1 <bar> '<,'>s/\%V\d\+/\=submatch(0) + vcount <cr>gv

And give it a friend:

xnoremap <C-x> :<C-u>let vcount = v:count ? v:count : 1 <bar> '<,'>s/\%V\d\+/\=submatch(0) - vcount <cr>gv

With those mappings you can do <C-a><C-a><C-a> and <C-x><C-x><C-x> while retaining the visual block or 8<C-a>/12<C-x>.

(endedit)

like image 42
romainl Avatar answered Oct 15 '22 21:10

romainl


You can run normal command on visually selected block. e.g. :normal! ^A then hit enter

like image 40
hawk Avatar answered Oct 15 '22 21:10

hawk