Vim: issue regarding copy and paste across different buffer - vim

I met a problem when copy some lines in one buffer to any buffer.
Here is the details.
For example, I use command '3yy' to copy 3 lines in buffer file1 and want use command 'p' to paste these lines in buffer file2. However, if I do a 'd' command between this two commands to delete some lines in either buffer, the 'p' command will not work anymore. It cannot paste the content I copied using '3yy' before.
I am on Vim Window 7.

The unnamed register contains what you yank and what you cut. You can…
use the 0 register which always contains the last yank: "0p
delete "for real" with the "black hole register": "_d.
See :help registers.

Just like DOOM said in the comment, 'd' will yank to the default register overwriting what you yanked previously. If you want to preserve what you yanked, place it in a register. Eg:
"13yy
will place 3 lines into register 1. You can paste them like this:
"1p

Related

How to visually select lines based on a search pattern in vim?

I've got some method calls all over the place in a large file, I'd like to match these lines, select and then yank them as one so I can put them all in a single place.
I can find all the lines I want with :g/>set but how do I visually select each line?
You can't have multiple visual selections in Vim.
But you can clear a register and append all the matching lines to it:
:let #a = ''
:g/>set/y A
then create an empty buffer (or navigate to an existing one):
:vnew
and paste from register a:
"ap
But you probably want something like TagList or TagBar.
edit
:[something]y a
means "yank into register a".
:[something]y A
means "append to register a".
What I usually do is :
Remove all the lines without the pattern :v/pattern/d
Select the whole new file with ggyG
Paste somewhere the result with p
Use undo a few times with u to get the file back to its initial state
This is a bit cumbersome, I would welcome a simpler solution.

How can I search for and then copy the lines in vi/vim?

I guess it is better to explain with an example, so here it is:
My useful line.
Some useless line.
Some other useless line.
Another useful line - oh I want this!
This is useful, I want this too!
In this example, I am searching for the string "useful". So, I want to copy lines 1, 4 and 5 to clipboard. How can I do this with vim?
First clear register a (you can use any letter a-z) for using.
:let #a=''
Then run the magic.
:g/useful/yank A
It will search for lines matching pattern "useful" and then run command :yank A to them. Capital A will append to the register a.
If your vim is configured with global Windows/X clipboards, you can run
:let #+=#a
to copy the register a's content to the clipboard.

How to replace the whole line with the text in the buffer in VIM?

Here is the text I'm working on:
line1: website = "a.com";
...
line3: website = "b.com";
...
line5: website = "c.com";
Suppose I want to change all website to "stackoverflow.com", I can do:
- change "a.com" to "stackoverflow.com"
- yank the whole line (Y)
- go to line3, hit p, k, dd to paste from buffer and delete the old "b.com" line.
Now the problem is that since dd puts the "b.com" into the buffer, to replace line5 I'll have to yank the whole line again.
Is there any simple way so that I can replace line3 and line5 with the already yanked line quickly?
UPDATE:
Thanks for the answers, now there are several ways doing it: delete to black hole, yank from named buffer, etc. I found this being my favorite method ( I use key R instead r as sometime I need to replace a single character):
In Vim is there a way to delete without putting text in the register?
I put some links to similar SO questions below:
How to Delete (desired text), delete (undesired text), and paste (desired text) in Vim
In Vim is there a way to delete without putting text in the register?
First things first
You can go one better by not needing to explicitly delete the line:
yank the whole line into register x: "xY
go to the next line to replace
visually select the whole line: V
paste over the selection from register x: "xp
Now the deleted line is in register ", as always, but the yanked line is still in register x, so you can repeat steps 2 through 4 without having to yank over and over.
Repeated things repeated
Unfortunately you cannot use . to repeat steps 3+4. So if you have to do this for a lot of lines, insert a few more steps to record a macro:
yank the whole line into a register x: "xY
go to the next line to replace
record a macro into the w register: qw
visually select the whole line: V
paste over the selection from register x: "xp
stop recording: q
go to the next line to replace
replay the macro recorded into w: #w
go to the next line to replace
and now finally, you can replay same-as-last-time: ##
Then you can simply repeat steps 9 and 10 for the next 50 lines you need to replace.
Last (repeated) things last
In fact, if you find the next line by searching, then you should use that search to go to the first line as well. Because then the n that you use to go to the next line can be included as part of the macro – basically you just swap steps 6 and 7.
Then you don’t have to manually go to the next line to replace at all, because the macro will send you there as the last thing it does. You can just keep hitting ##, along with any occasional ns whenever you happen to want to skip a particular match.
References
help "
help registers
help complex-repeat
You can use named buffers for this instead of the default unnamed buffer: "lY then "lp to yank resp. paste from register l, then let the dd use the default buffer.
This is not an answer to your question as put but it is an answer to your real question, I think.
Technique 1: Are you aware of :s? If you are just wanting to replace all matches, you could do something like this:
:%s/^website = "\zs.*\ze\.com";$/stackoverflow/
As you haven't specified precise format of it all and whether or not you are wanting to replace all or only some, I can't say whether this is what you want or not.
Technique 1b: Even if you only want to replace some, there's a useful and not terribly widely known flag for :s: c, "confirm". (See :help :s_flags and more specifically :help :s_c.) Then you can decide with each one whether you want to replace it or not.
:%s/^website = "\zs.*\ze\.com";$/stackoverflow/c
Technique 2: You could also search, replace and then repeat. /^website = "\zs.*\ze\.com";$, then cwstackoverflowEsc to replace the word with "stackoverflow". Then n to go to the next match and if you want to replace it with "stackoverflow", use ..
Rereading this question I think this is closer to what you're after:
In Vim is there a way to delete without putting text in the register?
E.g. instead of using dd use "_dd
The "0 register always contain your last yanked text. Then you can do:
change "a.com" to "stackoverflow.com"
yank the whole line (Y)
go to line3, hit "0p, k, dd to paste from buffer and delete the old "b.com" line.
go to line5, hit "0p, k, dd to paste from buffer and delete the old "c.com" line.
ci" - change inside the ""
ctrl-r 0 - put default register
jj - move down two lines
. - repeat last command
jj
.

How do I use vim registers?

I only know of one instance using registers is via CtrlR* whereby I paste text from a clipboard.
What are other uses of registers? How to use them?
Everything you know about VI registers (let's focus on vi 7.2) -- share with us.
Registers in Vim let you run actions or commands on text stored within them. To access a register, you type "a before a command, where a is the name of a register. If you want to copy the current line into register k, you can type
"kyy
Or you can append to a register by using a capital letter
"Kyy
You can then move through the document and paste it elsewhere using
"kp
To paste from system clipboard on Linux
"+p
To paste from system clipboard on Windows (or from "mouse highlight" clipboard on Linux)
"*p
To access all currently defined registers type
:reg
I was pleased when I discovered the 0 register. If you yank text without assigning it to a particular register, then it will be assigned to the 0 register, as well as being saved in the default " register. The difference between the 0 and " registers is that 0 is only populated with yanked text, whereas the default register is also populated with text deleted using d/D/x/X/c/C/s/S commands.
I find this useful when I want to copy some text, delete something and replace it with the copied text. The following steps illustrate an example:
Yank the text you want to copy with y[motion] - this text is saved in " and 0 registers
Delete the text you want to replace with d[motion] - this text is saved in " register
Paste the yanked text with "0p
where " is the command to use a register for the next command.
On the final step, if you were to paste from the default register (with p), it would use the text that you had just deleted (probably not what you intended).
Note that p or P pastes from the default register. The longhand equivalent would be ""p (or ""P) and "0 holds the last yank, "1holds the last delete or change.
For more info see :help registers.
One of my favorite parts about registers is using them as macros!
Let's say you are dealing with a tab-delimited value file as such:
ID Df %Dev Lambda
1 0 0.000000 0.313682
2 1 0.023113 0.304332
3 1 0.044869 0.295261
4 1 0.065347 0.286460
5 1 0.084623 0.277922
6 1 0.102767 0.269638
7 1 0.119845 0.261601
Now you decide that you need to add a percentage sign at the end of the %Dev field (starting from 2nd line). We'll make a simple macro in the (arbitrarily selected) m register as follows:
Press: qm: To start recording macro under m register.
EE: Go to the end of the 3rd column.
a: Insert mode to append to the end of this column.
%: Type the percent sign we want to add.
<ESC>: Get back into command mode.
j0: Go to beginning of next line.
q: Stop recording macro
We can now just type #m to run this macro on the current line. Furthermore, we can type ## to repeat, or 100#m to do this 100 times! Life's looking pretty good.
At this point you should be saying, "But what does this have to do with registers?"
Excellent point. Let's investigate what is in the contents of the m register by typing "mp. We then get the following:
EEa%<ESC>j0
At first this looks like you accidentally opened a binary file in notepad, but upon second glance, it's the exact sequence of characters in our macro!
You are a curious person, so let's do something interesting and edit this line of text to insert a ! instead of boring old %.
EEa!<ESC>j0
Then let's yank this into the n register by typing B"nyE. Then, just for kicks, let's run the n macro on a line of our data using #n....
It added a !.
Essentially, running a macro is like pressing the exact sequence of keys in that macro's register. If that isn't a cool register trick, I'll eat my hat.
Other useful registers:
"* or "+ - the contents of the system clipboard
"/ - last search command
": - last command-line command.
Note with vim macros, you can edit them, since they are just a list of the keystrokes used when recording the macro. So you can write to a text file the macro (using "ap to write macro a) and edit them, and load them into a register with "ay$. Nice way of storing useful macros.
The black hole register _ is the /dev/null of registers.
I use it in my vimrc to allow deleting single characters without updating the default register:
noremap x "_x
and to paste in visual mode without updating the default register:
vnoremap p "_dP
If you ever want to paste the contents of the register in an ex-mode command, hit <C-r><registerletter>.
Why would you use this? I wanted to do a search and replace for a longish string, so I selected it in visual mode, started typing out the search/replace expression :%s/[PASTE YANKED PHRASE]//g and went on my day.
If you only want to paste a single word in ex mode, can make sure the cursor is on it before entering ex mode, and then hit <C-r><C-w> when in ex mode to paste the word.
To make it more convenient :
cnoremap <c-g> <c-r>"
cnoremap <C-Right> <c-r><c-w>
A cool trick is to use "1p to paste the last delete/change (, and then use . to repeatedly to paste the subsequent deletes. In other words, "1p... is basically equivalent to "1p"2p"3p"4p.
You can use this to reverse-order a handful of lines:
dddddddddd"1p....
I think the secret guru register is the expression = register. It can be used for creative mappings.
:inoremap \d The current date <c-r>=system("date")<cr>
You can use it in conjunction with your system as above or get responses from custom VimL functions etc.
or just ad hoc stuff like
<c-r>=35+7<cr>
q5 records edits into register 5 (next q stops recording)
:reg show all registers and any contents in them
#5 execute register 5 macro (recorded edits)
From vim's help page:
CTRL-R {0-9a-z"%#:-=.} *c_CTRL-R* *c_<C-R>*
Insert the contents of a numbered or named register. Between
typing CTRL-R and the second character '"' will be displayed
<...snip...>
Special registers:
'"' the unnamed register, containing the text of
the last delete or yank
'%' the current file name
'#' the alternate file name
'*' the clipboard contents (X11: primary selection)
'+' the clipboard contents
'/' the last search pattern
':' the last command-line
'-' the last small (less than a line) delete
'.' the last inserted text
*c_CTRL-R_=*
'=' the expression register: you are prompted to
enter an expression (see |expression|)
(doesn't work at the expression prompt; some
things such as changing the buffer or current
window are not allowed to avoid side effects)
When the result is a |List| the items are used
as lines. They can have line breaks inside
too.
When the result is a Float it's automatically
converted to a String.
See |registers| about registers. {not in Vi}
<...snip...>
I use the default register to grep for text in my vim window without having to reach for the mouse.
yank text
:!grep "<CTRL-R>0"<CR>
Use registers in commands with #. E.g.:
echo #a
echo #0
echo #+
Set them in command:
let #a = 'abc'
Now "ap will paste abc.
One overlooked register is the '.' dot register which contains the last inserted text no matter how it was inserted eg ct] (change till ]). Then you realise you need to insert it elsewhere but can't use the dot repeat method.
:reg .
:%s/fred/<C-R>./
A big source of confusion is the default register ". It is important to know the way it works. It is much better if the default register is avoided most of the times. The explanation from the Vim documentation:
Vim fills this register with text deleted with the "d", "c", "s", "x" commands
or copied with the yank "y" command, regardless of whether or not a specific
register was used (e.g. "xdd). This is like the unnamed register is pointing
to the last used register.
So the default register is actually a pointer to the last used register. When you delete, or yank something this register is going to point to other registers. You can test that by checking the registers. There is always another register that is exactly the same as the default register: the yank register ("0) , the first delete register("1) , small delete register("-) or any other register that was used to delete or yank.
The only exception is the black hole register. Vim doc says:
An exception is the '_' register: "_dd does not store the deleted text in any
register.
Usually you are much better off by using directly: "0, "- and "1-"9 default registers or named registers.
My favorite register is the ':' register. Running #: in Normal mode allows me to repeat the previously ran ex command.
So we can verify some commands in with :MY_commandXXXXX then put MY_commandXXXXX in vimrc
My friend Brian wrote a comprehensive article on this. I think it is a great intro to how to use topics. https://www.brianstorti.com/vim-registers/
My favorite feature is the ability to append into registers by using capital letters. For example, say you want to move a subset of imports from buffer X to buffer Y.
Go to line x1 in buffer X.
Type "ayy to replace register a with the content of line x1.
Go to line x5.
Type "Ayy (capital A) to append line x5 at the end of register a.
Go to buffer Y and type "ap to paste
<content of line x1>
<content of line x5>

How do I yank all matching lines into one buffer?

How do you yank all matching lines into a buffer?
Given a file like:
match 1
skip
skip
match 2
match 3
skip
I want to be able issue a command to yank all lines that match a pattern (/^match/ for this example) into a single buffer so that I can put it into another doc, or into a summary or whatever.
The command should wind up with this in a buffer:
match 1
match 2
match 3
My first thought was to try:
:g/^match/y
But I just get the last match. This makes sense, because the :g command is effectively repeating the y for each matching line.
Perhaps there is a way to append a yank to buffer, rather than overwriting it. I couldn't find it.
:g/^match/yank A
This runs the global command to yank any line that matches ^match and put it in register a. Because a is uppercase, instead of just setting the register to the value, it will append to it. Since the global command run the command against all matching lines, as a result you will get all lines appended to each other.
What this means is that you probably want to reset the register to an empty string before starting: :let #a="" or qaq (i.e., recording an empty macro).
And naturally, you can use the same with any named register.
:help registers
:help quote_alpha
:help global
Using Vi/Vim: Ex and Ex-like Commands
:help registers
:help quote_alpha
Specify a capital letter as the register name in order to append to it, like :yank A.
Oh I just realized after commenting above that it's easy to yank matching lines into a temporary buffer...
:r !grep "pattern" file.txt
The simplest solutions come once you've given up on finding them. :)

Resources