How to select all LINES between parenthesises in VIM - vim

Say I have the following code
aaa;
bbb;
ccc void () {
xxx;
yyy;
}
ddd;
eee;
Now suppose my cursor is at yyy. I'd like to highlight all code between the parenthesis { and } inclusive of the complete line the brackets are on. This means the highlight will look like
before select
after select
va} is not a solution as that produces this

Effectively it should be a linewise selection. But the corresponding "text-object" forces a charwise one (so there's no difference between va{ and Va{).
However, you can make a selection linewise anytime. So va{V achieves the desired result.
I'm not sure if any mapping is needed at all. But at least ab should not be touched as it normally stands for parentheses ("()-block").
vnoremap aB aBV
Now vaB will select {}-block linewise, while va{ will do "normal" {}-block selection.

nmap vab va{$o0
Breaking it down
vab
highlights within the brackets inclusive of the brackets. The cursor finishes at the end of the highlight.
$
moves the cursor to the end of the line
o
moves the cursor to the other end of the highlight block
0
moves the cursor to the start of the line

Related

Insert lines of file into multi-line selection (visual block mode) in Vim

Let us assume that file 'file.txt' contains:
31
37
14
I would like to insert those lines into certain places of a Vim buffer (using perhaps visual block mode with Ctrl-v ??).
In other words, if file 'text.txt' contains
This is the beginning of a file with several lines
Age of Person A: ; Other info...
Age of Person B: ; Other info...
Age of person C: ; Other info...
This is the end of the file.
is it possible to insert the corresponding lines of 'file.txt' into the places before the ';' character at each selected line?
The desired result would be:
This is the beginning of a file with several lines
Age of Person A: 31; Other info...
Age of Person B: 37; Other info...
Age of person C: 14; Other info...
This is the end of the file.
Thanks.
Yes! Just highlight the numbers in visual block mode (C-v):
31
37
14
Yank them (y) and in normal mode place your cursor where I've put a |
symbol below:
This is the beginning of a file with several lines
Age of Person A:|; Other info...
Age of Person B: ; Other info...
Age of person C: ; Other info...
This is the end of the file.
and use the put command (p). You'll end up with:
This is the beginning of a file with several lines
Age of Person A: 31; Other info...
Age of Person B: 37; Other info...
Age of person C: 14; Other info...
This is the end of the file.
Assuming you are editing text.txt…
Edit file.txt:
:e file.txt<CR>
Select the lines in visual-block mode:
<C-v>Gl
Yank the block:
y
Switch back to text.txt:
<C-^> (or <C-6>, or :b#<CR>)
Move the cursor to where you want those numbers.
/;<CR>
Put the yanked text before the cursor:
P
Reference:
:help :edit
:help visual-block
:help G
:help l
:help ctrl-^
:help /
:help P
Just as an alternative answer, you may not have known (I didn't till now) that you can create Vim macros that work across files/splits.
For this problem, you can create a split to put the two files next to each other in the same Vim session:
Then on the destination file, move the cursor to the first line you want to modify, in this case Age of Person A. Now press q and any letter of your choosing to record the macro at that letter. Then once it's recording, I typed the following
^Whggdd^Wlpkf;d$jpkJ to go to the left window ^Wh (^W is ctrl+W), go to top line gg, cut line dd, move back to right window ^Wl, paste and rearrange the lines to get them in the right order pkf;d$jpkJ. Then I pressed q to stop the macro, and now you can apply the macro to every line you want with # and the letter you stored the macro in. In my case, I just did a visual block on the remaining lines and then typed :norm #a, since a was the letter I chose for my macro.
A little hackier, but the macros across files and splits might be useful feature to know.

How to move/shift around several rows in V-line mode using vim. Lines are 2 rows apart

For example, I want to select lines starting with B28, B29 and B30 using Shift + v in row B28 , then select row B29 and so on..., then press 'd' and then move to ROW 1 and press 'Shift-p' in the first row to paste all these rows there.
ROW 1
A26 51.00824
D26 35.94841
D27 35.94841
B28 7.07486
A28 35.95497
D28 179.99932
B29 4.15400
A29 90.00068
D29 179.99932
B30 7.07490
Visual mode(s) can only select contiguous regions (this applies to characterwise, linewise, and blockwise visual mode, regardless of the value of virtualedit). The only exception is ragged line-endings with, say, vip$.
But you can accomplish your goal other ways. For example:
:global/^B\d+/move /ROW 1/-
Should move all lines starting with B followed by digits to the line after ROW 1. (They will probably be reversed; in your case, a simple :sort n will probably be do, but generally :[range]!tac or :[range]global/./move <firstline> can reverse lines.)
Or, you could record a macro like so:
Mark insertion point: :/ROW 1/mark a
start a recursive macro in register q: qqqq (the first three clear the register)
go to next occurence to move /^B\d+
move it dd'ap
adjust mark ma
recursive invocation #q
fini q
Now hit #q and watch the magic.
If you needed to repeat the above many times for different things, I would write a series of commands to get it working once, then turn that into a function and generalize the things that are variable. Voilà, automation.
Another method, just for fun:
:g/^B/normal! dd1G}P
:g/^B/<cmd> executes <cmd> on every line starting with a B,
normal! <macro> executes normal mode macro <macro>,
dd cuts the line to the unnamed register,
1G moves the cursor to line 1,
} moves the cursor to the empty line after the current paragraph, this is key because it allows us to put the next line below the last one that was put and thus to respect order,
P puts the content of the unnamed register above the current line.
Reference:
:help :global
:help :normal
:help /^
:help dd
:help G
:help }
:help P
--- EDIT ---
There are plenty of ways to address your target, even if it is not on line 1.
With a line number:
:g/^B/normal! dd23G}P
With a mark:
ma
:g/^B/normal! dd'a}P
With a search:
:g/^B/normal! dd?ROW1^M}P " ^M is obtained with <C-v><CR>

Vim expand selection by a paragraph

If I have a visual selection in vim, how do I expand the selection to include the next paragraph? Also can I press o and do the same to select the previous paragraph?
You can use the ap or ip text-objects for "a paragraph" or "inner paragraph". A paragraph is a block of text separeated by blank lines. ap also includes the blank lines after the current paragraph. There is also { and } motions to move amongst paragraphs.
So to get the next paragraph you can do 2} or }ap.
For the previous paragraph, indeed, use o to go to the other end of your selection and 2{.
You can also add a count to ap, e.g 2ap will select the current and the next paragraph.

vim: insert successive numbers in a row

Let's say I want to initialize this tuple:
t = (
#(id, name)
(1, 'aasd'),
(2, 'bsfd'),
(3, 'asf'),
...
(21, 'aefae'),
)
I am sure I can do as follow with vim.
1/ Type this:
t = (
#(id, name)
(, 'aasd'),
(, 'bsfd'),
(, 'asf'),
...
(, 'aefae'),
)
2/ Visual select comma row, and type a tricky key sequence which would write successive number
Does anyone know what is the tricky key sequence I should type?
Instead of using VisIncr newer vims (starting with Version 8) support incrementing in visual mode. So I would go with:
Press Ctrl-V and mark the column with the commas
I1ESC to initialize each column to 1
Visually block select the second to last row (using e.g. gvj)
press gCtrl-A to have each row sequentially incremented.
This can be solved with a macro
Position the cursor on the first number: 3Gf1
Start recording: qq
Yank the number lyT, go one down j, paste P, increment ^A (Ctrl+ A), stop recording q.
Execute the macro for the remaining lines: 20#q
All together: 3Gf1lyT(jP^Aq20#q
To avoid the counting, and apply the increment until there are no more lines, you can also turn this into a recursive macro:
Position the cursor on the first number: 3Gf1
Clear macro register q and start recording: qqqqq
Yank the number lyT, go one down j, paste P, increment ^A (Ctrl+ A), re-invoke macro #q. All together: lyT(jP^A#q
Using the VisIncr plugin:
press Ctrl-v and mark the column with the commas (that is, where you want the numbers)
Shift-i1Esc - this should insert a column of 1s
gv - mark the column of 1s
:I - this should change the column of 1s into numbers 1 ... 21.

vim shortcut to traverse the word from right to left

Vim shortcut to traverse the words in forward direction i.e left to right is w / W
What is the shortcut to go in the opposite direction?
Similarly x deletes character on which cursor is there. So continuously pressing it deletes characters from left to right. Is there a shortcut to delete characters from right to left i.e characters before the cursor.
b goes backwards to the previous beginning of a word.
X will delete the character before the cursor
db will delete from the cursor position to the previous beginning of a word (excluding the letter at the cursor). e.g. ([] is the cursor position)
first middle la[s]t " type b
first middle [l]ast " type b again
first [m]iddle last " type db
[m]iddle last
Of course b is just a movement command, so you can tack it on to any command that takes a movement, e.g. cb will cut/change to the beginning of the word, vb will highlight it, etc.

Resources