vim copy-paste buffers - vim

Suppose I have the following text (I have numbered the lines for clarity) and the cursor is at the beginning of the 5th line:
1
2 var x = 1;
3 var y = 2;
4
5 if (true) {
6 print("Hey!");
7 }
Okay, now I try to cut the lines 5, 6, 7 (all that "if" thingy). For that purpose I do:
Vjjd. Now it appears I am at the beginning of the 4th line which is an empty string.
My question: is it possible at this moment to remove the 4th line without loosing previously copied lines 5, 6, 7 (that "if" thingy), so that I'll be able to paste them somewhere else, say, on the 1st line later?

You can always yank or delete into a register using "n, where n is just about any key. See a list of available registers in "help registers", some of which have special meaning. For example, you could do:
> "a3dd (to delete the last three lines into a register called a)
> dd (to delete the blank line)
> "ap (to paste the a register)
You can also use Vjj"ad, to match what you were doing in the original question.

Yes: You can use the blackhole buffer register: type "_dd

if your #4 line is empty line, it is easy, you don't have to play with register. just do:
kJ
it means:
k: move to #3
J: (shift-J) Join #3 and #4
or you prefer do it in INSERT mode.
i<BS>
or
I<c-u>
if that line is not empty:
using register to store the 3 lines or #4, like #Derek suggested
using blackhole register like #Jan suggest
or using numbered register.
say, now you just did 3dd (without named register), and cursor on a not-empty line (#4), you could directly do dd. the 3 lines are not gone. you can paste them again by:
"2p

Related

How to delete till backward in vim

I know how to delete until a char forward, like using dtx to delete till the x char from current cursor onwards. But how can I to do that backwards?
Say I have the following:
"abc I want to delete back to I"
And the cursor is at the end of the line, I want it to be "abc ".
In general, capital letters reverse. So we have:
t do something until a character
T do something BACKWARDS until a character
f do something until and including a character
F do something BACKWARDS until and including a character
I guess the problem is not how to remove till/to (T/F) the char backwards. You need delete the char under cursor too , in your case, the last I. leaving abc<space> at the end.
option 1: (3 key strokes)
You can move to the first I backwards, than D:
FID
option 2: (4 key strokes)
or move cursor to the beginning, do it forwardly.
0FID
option 3: (4 key strokes)
you can do an extra x.
dFIx
option 4: (4 key strokes)
with v:
vFIx
With cursor at end of line in normal mode, do dTc.

How can I make vim to format matrix side by side

I am using vim to log a lot of my day-to-day work. I usually have a lot of results with matrix. When I paste those at the end of the day I have pages of (sometimes) 0ne or 2 columns matrix
My question is how can I ask vim to programatically format
this:
R) DT = data.frame(x=rnorm(6),y=rnorm(6))
R) DT
x y
1 -0.0007499 0.7661
2 1.5559552 -0.6664
3 0.2082094 -0.1598
4 -0.1684766 -0.0536
5 3.1014233 -0.7439
6 0.1985104 2.0415
R) DT2 = data.frame(x=rnorm(7),y=rnorm(7))
R) DT2
x y
1 -0.005116 -0.4388
2 2.317381 0.6597
3 0.359883 0.4770
4 -1.426220 0.4911
5 0.468820 -0.3260
6 0.626147 -0.6254
7 -1.086660 2.1973
to this: side by side
R) DT = data.frame(x=rnorm(6),y=rnorm(6)) R) DT2 = data.frame(x=rnorm(7),y=rnorm(7))
R) DT R) DT2
x y x y
1 -0.0007499 0.7661 1 -0.005116 -0.4388
2 1.5559552 -0.6664 2 2.317381 0.6597
3 0.2082094 -0.1598 3 0.359883 0.4770
4 -0.1684766 -0.0536 4 -1.426220 0.4911
5 3.1014233 -0.7439 5 0.468820 -0.3260
6 0.1985104 2.0415 6 0.626147 -0.6254
7 -1.086660 2.1973
EDIT:
Thanks everybody, Kent solution worked, strangely before set ve=all my C-Q did not allow to select a block like
############
###############
#########
#########
#########
I couldn't reach the last column of the second line (using gvim on win XP).
Now works very well
I'll also use Ingo Karkat plugin"
try following steps:
:set ve=all
move cursor to beginning of line R) DT2 = data.frame(x=rnorm(7),y=rnorm(7))
press C-V, then using motion magic to select the 2nd block
press d
move cursor to the first line, the position you want to paste the 2nd block. type p
if your text is always like that format, you could try this mapping:
:nnoremap <leader>mt :let &ve='all'<cr>gg/^R)<CR>n<c-v>G$dgg$3lp  
 
then you could in normal mode type <leader>mt to do the transformation.
NOTE
I have no experience of vim on windows... so you may have to change the mapping for windows blockwise selection. <C-Q> ? not sure.
I assume the first line of the file is R)...
this will paste the 2nd block to the position: 3 spaces after the end of 1st line, change the number 3 in mapping if you want to adjust it
The key to this is blockwise visual mode. Go to the beginning of the second block (what should become the right column next to the first block), press Ctrl+V (on Windows, this is often remapped to Ctrl+Q), create the selection with $ and jjj. . ., then delete with d. Then go to the first line of the first block, $ to go to the end of line, (optionally append padding whitespace), then paste with p . The second block should be pasted to the right of your cursor. Finally, you can delete the empty lines left where the second block was.
My UnconditionalPaste plugin simplifies this task: You can then simply delete the second block with dd or Vjjj. . .d, and force a paste in blockwise mode with the plugin's gdp mapping.
If you find a way to determine the size of the blocks (the } key, which jumps to the next empty line, may come handy here), you can then put all of the steps into a custom mapping.

Move lines matched by :g to the top of the file

I have a large text file with several calls to a specific function method_name.
I've matched them using :g/method_name.
How would I move them to the top of the file (with the first match being on the top)?
I tried :g/method_name/normal ddggP but that reverses the order. Is there a better way to directly cut and paste all the matching lines, in order?
Example input file:
method_name 1
foo
method_name 2
bar
method_name 3
baz
Example output file:
method_name 1
method_name 2
method_name 3
foo
bar
baz
How about trying it the other way around: moving the un-matched lines to the bottom:
:v/method_name/normal ddGp
This seems to achieve what you want.
I think you can achieve the desired result by first creating a variable assigned
to 0:
:let i=0
And then executing this command:
:g/method_name/exec "m ".i | let i+= 1
It basically calls :m passing as address the value of i, and then increments
that value by one so it can be used in the next match. Seems to work.
Of course, you can delete the variable when you don't need it anymore:
:unlet i
If the file is really large, count of matching entries is small, and you don't want to move around the entire file with solution v/<pattern>/ m$, you may do this:
Pick any mark you don't care about, say 'k. Now the following key sequence does what you want:
ggmk:g/method_name/ m 'k-1
ggmk marks first line with 'k.
m 'k-1 moves matching line to 1 line before the 'k mark (and mark moves down with the line it is attached to).
This will only move a few matching lines, not the entire file.
Note: this somehow works even if the first line contains the pattern -- and I don't have an explanation for that.
For scripts:
normal ggmk
g/method_name/ m 'k-1

How can I quickly add something to a few lines in vim?

I'm trying to get away from my arrow use but there is one thing I've yet to solve without using the arrow keys. Take this example:
var1 = "1"
var2 = "2"
var3 = "3"
var4 = "4"
Now I want this to be:
var_1 = "1"
var_2 = "2"
var_3 = "3"
var_4 = "4"
Using arrows I would just goto the var1, insert and add the underscore and then arrow down and do the same thing. The problem with using hjkl is I can't be in insert mode so I have to esc out, move down, insert...rinse repeat which required more work. Is there another way to accomplish this?
You can also use a visual block insert:
go to the "1" in "var1"
press CTRL+V
go down with j to select all the rows you wish to affect
I (that's capital i)
_
<ESC>
The underscore should now be inserted at the correct place in all the rows selected (for some reason it takes a second for it to happen on my machine)
There are many ways to do this. Using movement commands for example:
1G0 → Go to the start of the first line
f1 → go to the first occurence of "1"
i_<ESC> → insert "_" and go back to normal mode
j. → go down a line and repeat the insert command
j. → go down a line and repeat the insert command
...
Or, better yet, use an "ex" command:
:%s/var/var_/
Or even with the visual block command, as johusman notes.
Assuming you're at line 1, character 1...
Using a macro:
qqfra_<Esc>+q3#q
q Record macro
q Into register q
f find
r 'r'
a append
_ underscore
Esc Normal mode
+ Start of next line
3 Three times
# Play macro
q from register q
Par 11.
Or (better) using substitute:
:%s!r!&_<CR>
Par 9!
[Sorry... too much VimGolf!]
I tend to prefer :substitute over the visual block mode.
%s/var\zs\ze\d/_/
I always have line numbers turned on, so I'd do e.g.
1,4 s/var/var_/
This is similar to the
% s/var/var_/
answer, but it only functions on the named lines. You can use visual mode to mark the lines, if you don't like typing the range (the 1,4 prefix) in your command.

How to add a word at the beginning of multiple lines in vim?

In Vim,
How do i add a word at the beginning of all lines?
Also how do i add it at end?
Eg..
If i have
A
B
C
D
I want to make it to
int A =
int B =
etc..
use visual block mode (Ctrl-v) to select the column you want, and then hit I, type the characters you want, and then hit Esc
So in this case, you'd put your cursor on A, hit Ctrl-v, go down to D, hit I and type int (it'll only appear on the first line while you type it), and then hit Esc at which point it'll apply that insert to all visually selected portions.
This works for anywhere in the document, beginning of line or end of line.
:he v_b_I for more info on Visual Block Insert
You can do this:
:%s/^/at the beginning/
:%s/$/at the end/
:%s/.\+/int & =
+ won't match on empty lines
If you need to copy just the first word, then do:
:%s/^\w\+/int & =/g
If you want to preserve indentation, then do:
:%s/^\(\s*\)\(\w\+\)/\1int \2 =/g
A global substitute should do i:
:%s/.\+/int & =/
This is how it works: in the second part of the substitution (ie in the int & =) the ampersand is replaced with what machted in the first part (the .*). Since .* matches the entire line, each line is subsituted as wanted.
If you have empty lines (in which you don't want to have any replacements), you could go with a
:%s/^\S\+$/int & =/

Resources