Vim Tips Wiki
m (Reverted edits by 220.227.4.171 (talk | block) to last version by 68.56.199.85)
(23 intermediate revisions by 9 users not shown)
Line 1: Line 1:
{{merged|605}}
 
 
{{TipImported
 
{{TipImported
|id=1011
+
|id=605
|previous=1010
+
|previous=604
|next=1012
+
|next=606
|created=October 6, 2005
+
|created=2003
 
|complexity=basic
 
|complexity=basic
|author=Jean-Christophe Clavier
+
|author=Yang Xiangyu
|version=5.7
+
|version=6.0
|rating=0/2
+
|rating=28/12
 
|category1=
 
|category1=
 
|category2=
 
|category2=
 
}}
 
}}
  +
A common requirement, particularly when programming, is to copy or delete text from one location, and use what was copied or deleted to replace text in one or more other locations. This tip describes how this operation is performed using standard Vim techniques, and with some tricks that may make it easier.
For those who use visual mode, here are some commands and mappings that may be useful:
 
  +
  +
==How to copy/paste==
  +
Copy a word and paste it over other words:
  +
{| class="cleartable"
  +
| style="width:5em" | <code>yiw</code> || yank inner word (copy word under cursor, say "''first''").
  +
|-
  +
| ... || Move the cursor to another word (say "''second''").
  +
|-
  +
| <code>viwp</code> || select "''second''", then replace it with "''first''".
  +
|-
  +
| ... || Move the cursor to another word (say "''third''").
  +
|-
  +
| <code>viw"0p</code> || select "''third''", then replace it with "''first''".
  +
|}
  +
  +
Copy a line and paste it over other lines:
  +
{| class="cleartable"
  +
| style="width:5em" | <code>yy</code> || yank current line (say "''first line''").
  +
|-
  +
| ... || Move the cursor to another line (say "''second line''").
  +
|-
  +
| <code>Vp</code> || select "''second line''", then replace it with "''first line''".
  +
|-
  +
| ... || Move the cursor to another line (say "''third line''").
  +
|-
  +
| <code>V"0p</code> || select "''third line''", then replace it with "''first line''".
  +
|}
  +
  +
Deleting, changing and yanking text copies the affected text to the unnamed register (<code>""</code>). Yanking text also copies the text to register 0 (<code>"0</code>). So the command <code>yiw</code> copies the current word to <code>""</code> and to <code>"0</code>.
   
  +
Typing <code>viw</code> selects the current word, then pressing <code>p</code> pastes the unnamed register over the visual selection. The visual selection that was just replaced is then stored in the default unnamed register.
First of all <tt>gv</tt> reselects the previous visual area.
 
   
  +
As you can see in the examples above, if you want to paste the same thing a second time, then you must use the <code>"0</code> register, as in <code>viw"0p</code>. A workaround is to remap the <code>p</code> command in visual mode so that it first deletes to the black hole register like so:
Prepare a <tt>:command</tt> on the previous visual selected area ('<,'> is slow to type):
 
 
<pre>
 
<pre>
  +
xnoremap p "_dP
map <M-:> :'<,'>
 
 
</pre>
 
</pre>
  +
Note, using <code>P</code> in the remap replicates the default visual mode <code>p</code> function. Feel free to test. And you'd use <code>xnoremap</code> instead of <code>vnoremap</code>, according to the [http://vimdoc.sourceforge.net/htmldoc/map.html#mapmode-x docs]. Now you don't have to worry about pasting from the <code>"0</code> register each subsequent time.
   
  +
However, this remapping prevents you from pasting from other registers in visual mode. So <code>viw"ap</code> to paste from the <code>"a</code> register is now broken. [https://code.google.com/p/lh-vim/source/browse/misc/trunk/macros/repl-visual-no-reg-overwrite.vim This script] may solve that. Alternatively, I guess you could use a leader key instead such as:
Copy the word under cursor in the clipboard:
 
 
<pre>
 
<pre>
  +
let mapleader=","
nnoremap <F4> "+yiw
 
  +
xnoremap <leader>p "_dP
 
</pre>
 
</pre>
  +
And then the workflow would be: <code>yiw</code>, move, <code>viw,p</code>, move again, <code>viw,p</code>, etc
   
  +
== Alternate method ==
Copy the visual selected area in the clipboard:
 
  +
  +
An alternate method is to do the paste/replace using <code>cw</code>. This method has the advantage of being easily repeatable using the <code>.</code> repeat command.
  +
  +
{| class="cleartable"
  +
| style="width:5em" | <code>yiw</code> || yank inner word (copy word under cursor, say "''first''". Same as above).
  +
|-
  +
| ... || Move the cursor to another word (say "''second''").
  +
|-
  +
| <code>ciw<C-r>0</code> || select "''second''", then replace it with "''first''" If you are at the start of the word then <code>cw<C-r>0</code> is sufficient.
  +
|-
  +
| ... || Move the cursor to another word (say "''third''").
  +
|-
  +
| <code>.</code> || select "''third''", then replace it with "''first''".
  +
|}
  +
  +
{{todo}}
  +
*Use with clipboard @+
  +
*Explain: Use register 2 to insert previously deleted text: <code>diw"2P</code>
  +
  +
This process works with any selected text, although it works best if:
  +
*The yanked text is characterwise and the replaced text is selected characterwise; ''or''
  +
*The yanked text is linewise and the replaced text is selected linewise; ''or''
  +
*The yanked text is blockwise and the replaced text is selected blockwise.
  +
  +
Typing <code>yiw</code> (yank inner word) is an example of a characterwise copy, while <code>yy</code> (yank current line) is an example of a linewise copy.
  +
  +
==Stamping==
  +
With this mapping, you can press <code>S</code> to replace the current word with the last yanked text. You can repeat the operation to replace words at different locations (move to another word and press <code>S</code>, then move to another word and press <code>S</code>, and so on). Each time you press <code>S</code>, the yanked text is "stamped" over the current word.
 
<pre>
 
<pre>
  +
nnoremap S diw"0P
vnoremap <F4> "+y
 
 
</pre>
 
</pre>
   
  +
The <code>S</code> command is then not available – use the equivalent <code>cc</code> command instead.
Replace the word under cursor with the content of the clipboard:
 
  +
  +
An alternative mapping uses the black hole register (<code>"_</code>) for the deletion so the unnamed register is not changed:
 
<pre>
 
<pre>
nnoremap <F5> viw"+p
+
nnoremap S "_diwP
 
</pre>
 
</pre>
   
  +
The alternative replaces the current word with the last text that was yanked or deleted. This means that you can copy or delete text from one location, then use that text to replace words in multiple other locations. However, if you delete any more text (for example, if you press <code>x</code> to delete an unwanted comma), the ability to easily use the previously-deleted text is lost.
Replace the visual selected area with the content of the clipboard:
 
  +
  +
In addition to the above, you could use the following to replace visually selected text with the last yanked text. Again, you can quickly repeat this by selecting some more text and pressing <code>S</code> to make the same change.
 
<pre>
 
<pre>
vnoremap <F5> "+p
+
vnoremap S "_d"0P
 
</pre>
 
</pre>
   
Prepare the :command to replace the word under cursor:
+
If you want to replace visually selected text with the last yanked or deleted text, use:
 
<pre>
 
<pre>
  +
vnoremap S "_dP
nnoremap &lt;S-F4> "+yiw:%s/\<<C-r>+\>/<C-r>+/gc<LEFT><LEFT><LEFT>
 
 
</pre>
 
</pre>
   
  +
==From tip 1011==
Prepare the :command to replace the selected area:
 
 
For those who use visual mode, here are some commands and mappings that may be useful:
  +
 
Type <code>gv</code> to reselect the previous visual area.
  +
 
Copy the current word or visually selected text to the clipboard:
 
<pre>
 
<pre>
 
nnoremap <F4> "+yiw
vnoremap &lt;S-F4> "+y:%s/\<<C-r>+\>/<C-r>+/gc<LEFT><LEFT><LEFT>
 
 
vnoremap <F4> "+y
 
</pre>
 
</pre>
   
 
Replace the current word or visually selected text with the clipboard contents:
I use the clipboard but you can use whatever register you want.
 
 
This puts "" around the word under cursor:
 
 
<pre>
 
<pre>
nnoremap <M-"> ciw"<C-r>+"<Esc>
+
nnoremap <F5> viw"+p
  +
vnoremap <F5> "+p
 
</pre>
 
</pre>
   
This puts "" around the visual selected area:
+
Prepare a <code>:substitute</code> command using the current word or the selected text:
 
<pre>
 
<pre>
vnoremap <M-"> c"<C-r>+"<Esc>
+
nnoremap <F6> yiw:%s/\<<C-r>"\>/<C-r>"/gc<Left><Left><Left>
 
vnoremap <F6> y:%s/\<<C-r>"\>/<C-r>"/gc<Left><Left><Left>
 
</pre>
 
</pre>
   
==Comments==
 
 
One key <F7> does everything. Good for inter-window copying and pasting.
 
One key <F7> does everything. Good for inter-window copying and pasting.
 
 
<pre>
 
<pre>
 
"copy
 
"copy
Line 71: Line 138:
 
"paste (Shift-F7 to paste after normal cursor, Ctrl-F7 to paste over visual selection)
 
"paste (Shift-F7 to paste after normal cursor, Ctrl-F7 to paste over visual selection)
 
nmap <F7> "zgP
 
nmap <F7> "zgP
nmap &lt;S-F7> "zgp
+
nmap <S-F7> "zgp
 
imap <F7> <C-r><C-o>z
 
imap <F7> <C-r><C-o>z
 
vmap <C-F7> "zp`]
 
vmap <C-F7> "zp`]
Line 80: Line 147:
 
</pre>
 
</pre>
   
  +
==See also==
  +
*[[Repeat last change]]
  +
  +
==Related Plugins==
  +
*{{script|id=2703|text=ReplaceWithRegister}} plugin to replace text covered by a motion, entire line(s) or the current selection with the contents of a register; more versatile and covers corner cases better than simple mappings
  +
*{{script|id=1234|text=YankRing}} - Maintains a history of previous yanks, changes and deletes
  +
*[https://github.com/maxbrunsfeld/vim-yankstack yankstack] - It allows you to yank and delete things without worrying about losing the text that you yanked previously. It effectively turns your default register into a stack, and lets you cycle through the items in the stack after doing a paste. This plugin is intended to be a simpler alternative to the YankRing plugin.
  +
*[https://github.com/svermeulen/vim-easyclip vim-easyclip] - This plugin solves that problem by redirecting all <code>c</code>hange and <code>d</code>elete operations to the black hole register and introducing a new operator, 'cut' (by default this is mapped to the <code>m</code> key for 'move').
  +
  +
==References==
  +
*{{help|registers}}
  +
*{{help|v_p}}
  +
 
==Comments==
  +
{{todo}}
  +
*Prune out any misguided information.
  +
*That will leave some notes on copying a word (or selected text) and pasting it to replace another word (or selected text).
  +
*There will also be some notes on visual mode which should be moved elsewhere (possibly 1584).
  +
  +
Related:
  +
*[[VimTip47|47 Swapping characters, words and lines]]
  +
*[[VimTip191|191 Transposing]]
  +
*[[VimTip438|438 Search and replace in a visual selection]]
  +
*[[VimTip646|646 Moving lines up or down in a file]]
  +
*[[VimTip1584|1584 Visual selection]]
  +
I hope some of these can be merged, while others will be "see also".
  +
  +
Copy/paste tips:
  +
*[[VimTip66|66 Transfer text between two Vim instances]]
  +
*[[VimTip71|71 Transfer text between two gvim sessions using clipboard]]
  +
*[[VimTip261|261 Close windows from gvim popup menu]]
  +
*[[VimTip312|312 Copy, cut and paste]]
  +
*[[VimTip344|344 Cut or copy lines without counting the lines]]
  +
*[[VimTip356|356 Quick yank and paste]]
  +
*[[VimTip386|386 Cut/copy and paste using visual selection]]
  +
*[[VimTip432|432 Putting the current file on the Windows clipboard]]
  +
*[[VimTip471|471 Using the mouse for Vim in an xterm]]
  +
*[[VimTip478|478 Copy the search results into clipboard]]
  +
*[[VimTip829|829 Copy and paste between Vim instances]]
  +
*[[VimTip834|834 Word-wise cut, copy and paste]]
  +
*[[VimTip964|964 GNU/Linux clipboard copy/paste with xclip]]
  +
*[[VimTip984|984 Accessing the system clipboard]]
  +
*[[VimTip1199|1199 Unconditional linewise or characterwise paste]]
  +
*[[VimTip1268|1268 Copy and paste between sessions using a temporary file]]
  +
*[[VimTip1593|1593 Smart paste]]
  +
*[[VimTip1623|1623 Using the Windows clipboard in Cygwin Vim]]
  +
I'm parking the copy/paste list here; later will work out which is "main" copy/paste tip and will move list there. [[User:JohnBeckett|JohnBeckett]] 11:24, September 28, 2009 (UTC)
  +
:I'd like for this tip to remain about copy/paste as it relates to visual mode, and we should have at least one other (separate) tip on the system clipboard (maybe more than one if specific systems have problems). One more that is a general "how to copy/paste" that also discusses use of registers would be good too. I don't want to see too much combination though, or the tip will probably become too big. --[[User:Fritzophrenic|Fritzophrenic]] 16:27, October 1, 2009 (UTC)
 
----
 
----
  +
I find it completely ridiculous that such a common operation is not more easily accomplished in VIM. Having to use the pinky finger to hit two far characters in <code>"_</code> or <code>"0"</code> is wholly inefficient. [http://vimcasts.org/blog/2013/11/registers-the-good-the-bad-and-the-ugly-parts/ And I am not the only one who is annoyed.] It is absolutely mind boggling that there is no clean way to accomplish this. Instead we have to resort to huge ass webpages describing all the workarounds and idiosyncrasies, and/or install a plugin. Notepad wins this one.
  +
:I have to say I agree this is an annoying quirk of Vim. But note it's there for a reason. Another common need is to move multiple blocks of text around, with one block replacing the next block which then needs to move elsewhere. Vim is optimized for this use case instead of "copy one block then replace a bunch of other blocks with it". Nevertheless, I admit I probably do the latter more often than the former so I do run into this a lot; I've just gotten in the habit of using register 0 when I'm replacing text rather than the unnamed register. --[[User:Fritzophrenic|Fritzophrenic]] ([[User talk:Fritzophrenic|talk]]) 21:04, July 15, 2014 (UTC)
  +
::I understand the use case for the 'feature'. But that's what named registers are for. I think really the problem is the stupid choice to 'cut' with the <code>d</code> and <code>c</code> commands. The implementation is poor when you have to rely on the pinky finger to type all three keypresses as in <code>"0p</code>. Have you just trained yourself to be super fast with that? Because I cannot do it fast at all.

Revision as of 10:36, 26 December 2014

Tip 605 Printable Monobook Previous Next

created 2003 · complexity basic · author Yang Xiangyu · version 6.0


A common requirement, particularly when programming, is to copy or delete text from one location, and use what was copied or deleted to replace text in one or more other locations. This tip describes how this operation is performed using standard Vim techniques, and with some tricks that may make it easier.

How to copy/paste

Copy a word and paste it over other words:

yiw yank inner word (copy word under cursor, say "first").
... Move the cursor to another word (say "second").
viwp select "second", then replace it with "first".
... Move the cursor to another word (say "third").
viw"0p select "third", then replace it with "first".

Copy a line and paste it over other lines:

yy yank current line (say "first line").
... Move the cursor to another line (say "second line").
Vp select "second line", then replace it with "first line".
... Move the cursor to another line (say "third line").
V"0p select "third line", then replace it with "first line".

Deleting, changing and yanking text copies the affected text to the unnamed register (""). Yanking text also copies the text to register 0 ("0). So the command yiw copies the current word to "" and to "0.

Typing viw selects the current word, then pressing p pastes the unnamed register over the visual selection. The visual selection that was just replaced is then stored in the default unnamed register.

As you can see in the examples above, if you want to paste the same thing a second time, then you must use the "0 register, as in viw"0p. A workaround is to remap the p command in visual mode so that it first deletes to the black hole register like so:

xnoremap p "_dP

Note, using P in the remap replicates the default visual mode p function. Feel free to test. And you'd use xnoremap instead of vnoremap, according to the docs. Now you don't have to worry about pasting from the "0 register each subsequent time.

However, this remapping prevents you from pasting from other registers in visual mode. So viw"ap to paste from the "a register is now broken. This script may solve that. Alternatively, I guess you could use a leader key instead such as:

let mapleader=","
xnoremap <leader>p "_dP

And then the workflow would be: yiw, move, viw,p, move again, viw,p, etc

Alternate method

An alternate method is to do the paste/replace using cw. This method has the advantage of being easily repeatable using the . repeat command.

yiw yank inner word (copy word under cursor, say "first". Same as above).
... Move the cursor to another word (say "second").
ciw<C-r>0 select "second", then replace it with "first" If you are at the start of the word then cw<C-r>0 is sufficient.
... Move the cursor to another word (say "third").
. select "third", then replace it with "first".

 TO DO 

  • Use with clipboard @+
  • Explain: Use register 2 to insert previously deleted text: diw"2P

This process works with any selected text, although it works best if:

  • The yanked text is characterwise and the replaced text is selected characterwise; or
  • The yanked text is linewise and the replaced text is selected linewise; or
  • The yanked text is blockwise and the replaced text is selected blockwise.

Typing yiw (yank inner word) is an example of a characterwise copy, while yy (yank current line) is an example of a linewise copy.

Stamping

With this mapping, you can press S to replace the current word with the last yanked text. You can repeat the operation to replace words at different locations (move to another word and press S, then move to another word and press S, and so on). Each time you press S, the yanked text is "stamped" over the current word.

nnoremap S diw"0P

The S command is then not available – use the equivalent cc command instead.

An alternative mapping uses the black hole register ("_) for the deletion so the unnamed register is not changed:

nnoremap S "_diwP

The alternative replaces the current word with the last text that was yanked or deleted. This means that you can copy or delete text from one location, then use that text to replace words in multiple other locations. However, if you delete any more text (for example, if you press x to delete an unwanted comma), the ability to easily use the previously-deleted text is lost.

In addition to the above, you could use the following to replace visually selected text with the last yanked text. Again, you can quickly repeat this by selecting some more text and pressing S to make the same change.

vnoremap S "_d"0P

If you want to replace visually selected text with the last yanked or deleted text, use:

vnoremap S "_dP

From tip 1011

For those who use visual mode, here are some commands and mappings that may be useful:

Type gv to reselect the previous visual area.

Copy the current word or visually selected text to the clipboard:

nnoremap <F4> "+yiw
vnoremap <F4> "+y

Replace the current word or visually selected text with the clipboard contents:

nnoremap <F5> viw"+p
vnoremap <F5> "+p

Prepare a :substitute command using the current word or the selected text:

nnoremap <F6> yiw:%s/\<<C-r>"\>/<C-r>"/gc<Left><Left><Left>
vnoremap <F6> y:%s/\<<C-r>"\>/<C-r>"/gc<Left><Left><Left>

One key <F7> does everything. Good for inter-window copying and pasting.

"copy
vmap <F7> "+ygv"zy`>
"paste (Shift-F7 to paste after normal cursor, Ctrl-F7 to paste over visual selection)
nmap <F7> "zgP
nmap <S-F7> "zgp
imap <F7> <C-r><C-o>z
vmap <C-F7> "zp`]
cmap <F7> <C-r><C-o>z

"copy register
autocmd FocusGained * let @z=@+

See also

Related Plugins

  • ReplaceWithRegister plugin to replace text covered by a motion, entire line(s) or the current selection with the contents of a register; more versatile and covers corner cases better than simple mappings
  • YankRing - Maintains a history of previous yanks, changes and deletes
  • yankstack - It allows you to yank and delete things without worrying about losing the text that you yanked previously. It effectively turns your default register into a stack, and lets you cycle through the items in the stack after doing a paste. This plugin is intended to be a simpler alternative to the YankRing plugin.
  • vim-easyclip - This plugin solves that problem by redirecting all change and delete operations to the black hole register and introducing a new operator, 'cut' (by default this is mapped to the m key for 'move').

References

Comments

 TO DO 

  • Prune out any misguided information.
  • That will leave some notes on copying a word (or selected text) and pasting it to replace another word (or selected text).
  • There will also be some notes on visual mode which should be moved elsewhere (possibly 1584).

Related:

I hope some of these can be merged, while others will be "see also".

Copy/paste tips:

I'm parking the copy/paste list here; later will work out which is "main" copy/paste tip and will move list there. JohnBeckett 11:24, September 28, 2009 (UTC)

I'd like for this tip to remain about copy/paste as it relates to visual mode, and we should have at least one other (separate) tip on the system clipboard (maybe more than one if specific systems have problems). One more that is a general "how to copy/paste" that also discusses use of registers would be good too. I don't want to see too much combination though, or the tip will probably become too big. --Fritzophrenic 16:27, October 1, 2009 (UTC)

I find it completely ridiculous that such a common operation is not more easily accomplished in VIM. Having to use the pinky finger to hit two far characters in "_ or "0" is wholly inefficient. And I am not the only one who is annoyed. It is absolutely mind boggling that there is no clean way to accomplish this. Instead we have to resort to huge ass webpages describing all the workarounds and idiosyncrasies, and/or install a plugin. Notepad wins this one.

I have to say I agree this is an annoying quirk of Vim. But note it's there for a reason. Another common need is to move multiple blocks of text around, with one block replacing the next block which then needs to move elsewhere. Vim is optimized for this use case instead of "copy one block then replace a bunch of other blocks with it". Nevertheless, I admit I probably do the latter more often than the former so I do run into this a lot; I've just gotten in the habit of using register 0 when I'm replacing text rather than the unnamed register. --Fritzophrenic (talk) 21:04, July 15, 2014 (UTC)
I understand the use case for the 'feature'. But that's what named registers are for. I think really the problem is the stupid choice to 'cut' with the d and c commands. The implementation is poor when you have to rely on the pinky finger to type all three keypresses as in "0p. Have you just trained yourself to be super fast with that? Because I cannot do it fast at all.