How to copy/paste text from vi to different applications - vim

Is it possible to copy/paste text without using :vs? If I have two vi windows open, I can copy/paste text with a mouse. How can I do it with a keyboard?
I found two existing questions that are similar to this, but neither one answers my question.
how to copy codes in vi to clipboard
Copy and paste content from one file to another file in VI

I'm sure there are many ways, but I do it using marks and registers.
Marks
You can place a mark anywhere in a file using m followed by the name of the mark you want to use.
You can use any letter between a and z (capital and lowercase) to name your marks.
You can go to the line that contains a mark with the ' key.
For example, mx marks a line with mark x and 'x moves the cursor to the line containing mark x.
You can go to the exact location of a mark using the backtick key: `
To yank from the current cursor location to the line containing mark x, for example, you would enter y'x
Registers
In order to use the clipboard, you need to use registers, which represent places you can store the text you yank.
Just like you can use different marks for each character, you can name the registers you yank text to.
You refer to a register by using the " key when yanking/putting.
For example "ay'x would yank the text between the cursor and the line containing x to register a.
The clipboard is represented by a special register: either * or + depending on your environment.
To yank the text between the cursor and the line containing mark x to the clipboard, enter the following: "+y'x
This says: use buffer + (the clipboard) to store the text between the cursor and the line containing mark x.
Once you do this, your text will be in the clipboard. You can use CONTROL-V to paste it into other apps.
NOTE: In some environments, the clipboard is represented by the buffer named *.
This may sound overwhelming, but once you get used to it, it's VERY powerful.
I use this hundreds of times every day.
If you're editing a file that has several key points of interest, you can mark each part of the file with different marks and quickly move your cursor between the code you need to edit.
Likewise, if you have several pieces of text that you need to repeatedly copy, you can store each one in a different register to make your pasting more efficient.

You can copy/paste by using the + register (read more: Accessing the system clipboard)
"+gyywill yank a line, and put it into the + register. You can paste in your other window with "+p in normal mode, or Ctrl+r + while in insert mode.
If you don't wish to use split windows, there really is no other way to paste between windows apart from using the system clipboard.

#up exhausted the subject. I can just add that most of the combination related is with associated with system key combination find you in config for Gvim (eg. windows mapping for CTRL+C CTRL+V etc. is in mswin.vim)

Related

Is it possible to simultaneously get the contents of a visual selection into a register and replace all the characters?

Consider the following text file.
Replace and yank this portion Ignore this portion
Suppose I have visually selected the part that says Replace and yank this portion.
I can take one of the following actions at this point.
I can use y to yank the contents into a register, but this destroys the visual selection.
I can use rx to replace each of the characters with an x, but this also destroys the visual selection.
Is it possible to simultaneously put the visual selection into a register and replace each of the characters in the visual selection with an x?
That is, I'm looking for a sequence of commands that result in the selected text being in a register, and each character in the selected text replaced by x. I'm not picky about which register.
Immediately after posting this question, I realized that all I needed was to be able to re-select the text that was just selected.
A quick Google search led to using gv for re-selection.
Thus, the final command sequence to achieve the desired effect is ygvrx. This will first yank the sequence into the register, re-select the previous selection, and then replace the characters.
Visually select the text and press c for change. Type the text you want and press <esc>. The text that was there before (in this case Replace and yank this portion) is now in your "" register, so you can just hit p as soon as you want to paste it.
type :h reg to see a list of all registers and what text you have inside them.

Vim: How do I paste a column of text (from clipboard) after a different column of text?

I'm testing proxies with my script that looks like that:
$proxy = "http://name:pass#133.245.122.91:80";
$proxy2 = "http://name:pass#133.245.229.241:80";
$proxy3 = "http://name:pass#133.245.113.197:80";
...
$proxy100 = "http://name:pass#133.245.212.197:80";
I get new proxies by email so can I copy new proxies and insert it instead of the old ones by Vim:
"http://name:pass#133.245.122.91:80";
"http://name:pass#133.245.229.241:80";
"http://name:pass#133.245.113.197:80";
...
"http://name:pass#133.245.212.197:80";
Right know I'm doing it as was described on this page How do I paste a column of text after a different column of text in Vim?
Use visual block (ctrl-v) to cut the letter column. Then move to the
first line of the number column. Move to the end and make one space.
Then paste the letter column.
I'm curious, how it can be done without extra step, just paste data from clipboard?
The short version: you can't. There are ways around it, but they aren't necessarily simpler. Longer version follows.
Vim has three ways of marking regions of text: linewise (you start this mode when you press V), characterwise (triggered when you press v), and blockwise (when you press Ctrl-v). The marked region is copied to a register, and this register has an attribute, the "type", that reflects the way you did the marking, linewise, characterwise, or blockwise. What happens when you paste from a register depends on this type.
Now, when you copy from system's clipboard the result is stored in the * register, and the type is always set to linewise. Thus you can't paste a column mode "without extra step". You can however set the type of the * register to blockwise before pasting:
call setreg('*', #*, 'b')
Thus, replacing the list of your proxies would go something like this:
copy the new list to clipboard, from the mail message
run :call setreg('*', #*, 'b') to set the type of the * register to blockwise
go to the old list, press Ctrl-v and mark it; assuming there's nothing else in the file aside from the proxies, a Vim golfer's way of doing that might be something along the lines of:
f" - go to the first "
Ctrl-v - start marking
?;Enter - go to the last ;
paste the new list over the selection, with "*p.
You can simplify the last step a little, by making the * and + registers always refer to the same value. To do that, add this to your vimrc:
set clipboard=unnamedplus,autoselect,exclude:cons\\\\|linux
With this setting the incantation becomes:
copy the new list from mail
run :call setreg('+', #+, 'b')
go to the old list and mark it with Ctrl-v as above
press p to paste the new list over it.
You don't need this dance if you have the new list in a file that you can open with Vim:
open the file with the old list
open the file with the new list in a separate copy of Vim
mark the new proxies with Ctrl-v and yank them with y
in the other Vim mark the old list with Ctrl-v and paste the new one over it with p.
This still involves using the system clipboard under the hood, but the second copy of Vim takes care of setting the type of the relevant register to blockwise.
I don't know any direct way to do this. If it is really important to you, you will probably need some set up before you do the actual editing, which only adds to the amount of typing you have to do (however you can add commands to your vimrc to make it permanent). You might set up some keyboard macro, or use the following map command:
:imap <CR> <Esc>j011lC
Now move to the first " sign and press C, then start pasting (only works in a terminal). Whenever you paste a newline, the map will move you to column 11 in the next line.
Remember to :iunmap <CR> when you are done.

How can vim keep the content of register when pasting over selected text?

I have a line of text I have yanked yy. Now I want to use this text to replace lines at several other places. The trouble is that when I select V the line to be replaced, and paste p, the text that was selected is automatically yanked! That's what I don't want.
Changing the register does not work, because both the paste and the yank are done with the newly selected register.
What is the command to keep the content of the register when pasting over selected text?
Your original selection should remain in register 0. So you can move through the file and paste your yanked line over other lines using: V"0p
Each time you p over something it goes into the default register.
To work around this feature you have to use "_, "the black hole register", before you p. Here is a custom mapping I have in my ~/.vimrc:
vnoremap <leader>p "_dP
It deletes the selected content and drops it in the black hole register (this means that the selected text disappears forever) and puts the content of the default register in place of the previously selected text while leaving the default register intact.
I use it often when I need to replace a loooooooong url in a few places with another looooooong url and crafting a s// would be too cumbersome.

In Vim is there a corresponding change (c) command for paste (p)?

With insertions, it is very easy to both wipe out a word/section and insert over it, like so
cw delete until end of word (with space) then go to insert mode
ce delete until end of word (without space) then go to insert mode
c3w delete until end of the next 3 words (with space) then go to insert mode
ct. delete until before period then go to insert mode
c$ delete until end of line then go to insert mode
How do I do this with paste operations? Often times I have a line like so
var name = "John Smith"
var name = "Jane Smith"
And I change it to
var name = "John Lee"
var name = "Jane Smith"
And yank (yw) "Lee", but now if I delete (dw) "Smith" from "Jane Smith", I no longer have "Lee" in the register to paste back. I know I can use the named registers. Also, I am sure I can use visual mode. However, I figured since this is a pretty common task, there would be a way to use the movement operators (e, w, t/T, f/F,$,0) with the paste command to specify what to paste over.
I think visual mode is the way to go. You just enable visual mode with v or V (if you want to overwrite whole lines at the time), use the movement operators in the usual way to select the area to be replaced and then paste. You take advantage of what you already know.
Vp overwrites the current line. vwp overwrites the current word.
You can find an overview of the alternatives at the Vim Wikia.
Oh yes, what you want is the ultra convenient (sarcasm) blackhole register: select in visual mode the part you want to replace, using the movement you want (like vw), then "_xP.
The black hole register _ is a special register akin to /dev/null. The operation " sets the destination register for the text you are about to replace, and thus "_ ensures that the unwanted "Smith" hits the blackhole register. Thus, "Lee" is preserved in the " register. I'd recommend using macros to help if you're doing this many times in a row.
I no longer have "Lee" in the register to paste back.
Actually, Lee is in reg:0, there are at least two ways to paste back.
Method 1
move cursor to Lee, yw
move cursor to Smith, dw
"0P
Method 2
move cursor to Lee, yw
move cursor to Smith, cw
Ctrl-R+0
You can always make a custom mapping, I have the following:
nnoremap ,pw viw"0p
Which pastes over the inner word (iw) the last yanked text. Note that I'm using the 0 register, so I can paste as many times as I want, without loosing the yanked text. Unfortunately you need to write some other mappings. I like to have a mapping to paste inside quote, inside brackets and inside parentheses:
nnoremap ,pi" vi""0p
nnoremap ,pi] vi]"0p
nnoremap ,pi) vi)"0p

Paste multiple times

What is the best way replace multiple lines with the contents of the clipboard?
The problem I'm having is when I yank a line and paste it over another line the "yank" is replaced with the line I just replace. Now, if I want to replace another line with the same line I have to go back up and yank it again.
There's got to be a better way to do this.
I have this in my .vimrc:
xnoremap p pgvy
(note: this will work only with the default register, but this mapping is easy to remember). Writing a more elaborate version would be possible. Also, you still can use P to get the old behaviour.
"0 should have the contents of your yank. It's a bit more tedious to type, but "0p should do what you want.
Alternatively, don't select-and-replace the old lines up front. If you find those lines with a search, just hit n. over and over (after an initial p), then when they're all pasted, do ndd followed by as many n.s as necessary.
The biggest mental switch I've needed to make when moving to Vim is to figure out how to apply group edits sequentially. I.e. rather than doing a bunch of edits on a line and then doing a bunch of the same edits on another line, I'll do the first edit on a bunch of lines (using . to great effect), then the second edit on a bunch of lines, etc. Alternatively, the use of macros may help as they are fantastic, but sometimes a little more tedious to get working correctly with "complex" changes.
I often use another registry, copy the line you need to some named registry "ay and then paste from there "ap
When you paste over a selection in Vim it will replace the default register with the contents of the selection. If pasting over a selection is wiping out the contents of the clipboard register then very likely you have the following line in your .vimrc
set clipboard=unnamed
One option is to remove that and use the explicit clipboard register "+
Another option is to use any of the other explicitly named registers (a-z). After the first paste yank the line back into "c for example and then use "cp to paste from there on out.
Instead of using copy/paste, it is often better to use a text object command such as ciw to change the inner word. This method has the advantage of being easily repeatable using the . repeat command.
yiw Yank inner word (copy word under cursor, say "first").
... Move the cursor to another word (say "second").
ciw<C-r>0 Change "second", replacing it with "first" ( is Ctrl-R).
... Move the cursor to another word (say "third").
. Change "third", replacing it with "first".
use np where n is the number of how much time you want to paste the lines eg 3p will paste 3 lines.

Resources