Cut, Copy, & Paste in Vim

Cut, Copy, & Paste

Before we get to any of these, remember that in a graphical Vim client like MacVim all your normal OS cut, copy, and paste commands like ⌘x, ⌘c, and ⌘v (on the Mac) will work just fine when combined with mouse selections. The following commands will make a huge difference in your speed because, they’ll enable you to efficiently rearrange code without ever reaching for the mouse. While you don’t need to start using these immediately I would strongly encourage you to practice with them until they’re comfortable and normal.

Vim’s got some odd verbs for Cut, Copy, and Paste. This is probably because it was written long before those were common terms. Instead of Cut, Copy, and Paste we have Yank (y), Delete (d), and Put (p). These are the most common of Vim’s verb. You combine them with various motion commands to quickly select the text you want to manipulate.

Quick Usage

The simplest, and most common way of interacting with Yank, Delete, and Put is by line. For example: Imagine you have the following function.

def awesome?(thing)
	thing.possesses_greatness? ? true : false

You might decide that it’s crap and you want to delete the whole thing. One way is to put your cursor on the first line and tell vim you want to delete that line and the next two. d2 The number is always the number of lines after the current one that you want included. What if you wanted only the current line? dd

If wanted to move it you’d, again, delete it from where it is, move your cursor to where you want it to go, and Put it with p

Yank (Copy) works exactly the same as delete except it leaves the text in place and you use y instead of d

In the long run this is amazingly useful and guaranteed to save you a ton of time, especially when you combine it with search and jumping to different line numbers directly. There is a slightly frustrating bit which you probably noticed: the counting. “Ok, I’m on line 148, and this method ends on line 186, but i don’t want to delete the last end so.. 185.. 85 minus 48 is… but i need to subtract one right? because i don’t want the first line? or… no. fuck.”

Yeah. Mental math is not my forte. If you’re like me, then read the line numbers post to see a trivial way to switch your sidebar to relative line numbers, and save yourself the headache.

Ready for more? I’m going to cover a bunch of common use cases here, but definitely check out the post on movement, and remember that pretty much anything you can do to move the cursor can be combined with these verbs so… dn Just keep whacking those two keys and it’ll keep deleting up to the next match. No counting required.

Delete (Cut)

Deleting Lines

d is the key to _d_eleting lines. As noted above, you can just whack it twice ( dd ) to affect just the current line. If you want to delete the current line and the 4 after it you type d4<RETURN>

Deleting parts of lines.

Deleting to the end of the line

D will delete everything from your cursor to the end of the line. Because $ means end of line you can combine d with the instruction to move to the end of the line: d$

Deleting arbitrary sections

This is my test sentence.

Let’s say we have our cursor on the “i” in “is” and we want to delete everything up to, but not including, “test”. We can “Delete To ’t’” by typing dtt<RETURN> and the sentence will become “This test sentence.” Deleting up to “sentence” is a little trickier. dts would “Delete To ’s’” and the first “s” is in “is”. So, we’d have to say 3dts because the “s” in sentence is the 3rd “s”.

Counting letters sucks, so don’t do it.

Remember when I said that searching was “…a tool for extending your selection, deleting chunks, and more”? Well, here’s where we use that.

You want to Delete everything up to (but not including) “sentence”, so hit d then start a search for “sentence” (d/) as you type in your search string Vim will highlight it it as you go. When I’ve typed the “s” it’s matching the “s” at the end of “is”…

as soon as I add the “e” it jumps ahead to the first “se” which happens to be exactly what I’m looking for.

Hit <RETURN> as soon as you’ve found the right place and it will delete everything up to, but not including, your match. This will cross lines too. If your search doesn’t find what you’re looking for, just hit <ESC>.

Advanced form…

What if you want the next search result? You can’t type n for next because vim will think you want “n” as the next letter of your search term, and you can’t hit <RETURN> on the first match because it’ll delete everything up to that, which isn’t enough.

You’ve got a couple options here. If you literally want the “next” match you can say 2d/<search tearm> which will delete to the 2nd match of the search term. Of course, now we’re right back to counting things. There’s a simpler way but it’s not quite as efficient.

When you delete with a search that search is now defined as the last thing you searched for (duh), but that means that n will work for finding the next one, and since n is a way to move your cursor, and I said you can combine movement with these verbs.

Deleting characters

x deletes whatever is currently selected. Keep whacking it and it’ll keep deleting whatever’s under the cursor. X deletes the character before the one that’s selected. Neither can be combined with motion commands.

What happened to d? Why are we talking about x? No clue. Practically speaking, I just use x as a delete key since Apple has decided that the key that says “delete” is actually a backspace key1. If I want to do anything more sophisticated than watching the characters slide into its gaping maw I will use d.

Yank (Copy)

y is the key to copying things. Like Delete you can just whack it twice (yy) to affect just the current line. All things that you can do to select multiple lines for Deletion work for Yanking.

Yank to end of line

Like with Deletion you can combine y with the command to move to the end of the line to Yank to the end of the line: y$

Put (Paste)

p will put whatever you have Yanked or Deleted into the doc wherever the cursor is currently located. If you have a line on the vim’s clipboard (not the OS’s clipboard) it will paste it on the line below the cursor. If just you have some characters, they will it will paste after the cursor.

P will paste lines above the current line and charters before the cursor.

Noticing a pattern? Many of Vim’s commands have upper case versions that do something very similar.

Pasting code into a terminal Vim with your OS’s paste command will frequently result in code with way too many levels of indentation. Because of the way terminals work, Vim can’t tell the difference between a paste from the system clipboard and you typing really fast. Normally it’ll say, “oh, you’re 2 indent levels in. When you hit enter I’ll go ahead and maintain that indent level for you” But you’re pasting code with 2 indent levels so you get 2 levels from vim plus 2 levels from your code, and then it hits return and now you’re 4 levels in plus 2 more on the next line of code and and and….

Vim, of course, has a way to address this.

set paste
" and
set nopaste

run set paste when you’re about to paste from the system clipboard and set nopaste when you’re done. You only have to do this in the terminal. The GUI versions like MacVim can tell when you’re pasting and handle it correctly.

Interacting with the system clipboard.

Beginners should skip this section. Seriously. All you need to know is that your normal system’s cut and copy functionality interacts with the system clipboard as you would expect. Or to put it another way: use ⌘c and ⌘x and everything will work just fine.

What follows will seem overwhelming to a beginner and “oh, just a quote mark?” to people already comfortable with yank and delete. I don’t want you to feel overwhelmed.

Vim has a series of registers where it stores things you’ve recently yanked or deleted. Your system also has a clipboard (usually just one) where it stores stuff you’ve recently copied or cut. These are not the same “clipboard” but Vim does have access to the system clipboard.

Yanking & Deleting to the system clipboard

Normal Yank and Delete have no effect on your OS’s clipboard. So, yanking and deleting in Vim won’t let you paste into another app. Some people may think this is good. I hit y, d and x so many times in a session that I’d have absolutely no clue what was on my clipboard if it always shoved them onto the system clipboard.

But Vim a special register just for interacting with the system clipboard. It’s named * Now, I have to step back a bit and explain that whenever you yank, or delete you’re putting that text into a register. If you want to use this functionality I recommend you see the buffers post for details, but here’s the quick, no-frills version.

Prefacing your yank or delete with " tells vim you want to shove it into a numbered or named buffer. It expects the buffer name / number afterwards, and the one for the system clipboard is named *, so "* Next add whatever you would normally do for the y or d selection. For example to yank the current line and the next two into the system clipboard, you’d say "*y2 and yes, you can combine this with search and t and anything else normal yanking and deleting allow.

On a related note: You can also have visual selections automatically copied to the system clipboard by adding this to your .vimrc I’m not a huge fan. It keept surprising me when I had it on, so I turned it off. It’s worth a try, but I’d recommend waiting until you’ve started to get comfortable with Vim.

set go+=a

Graphical Vim’s and Cut / Copy / Paste

The only gotcha with the graphical clients is that each window should be considered its own world. The OS level cut / copy / paste will transfer things between windows, but the built in commands noted below will only transfer stuff between buffers or tabs within the same window. This is, presumably, because every terminal window is its own little world, and the same functionality carried over to the graphical clients.

Additional Reading

When you’ve recovered from reading far too many words about Cut, Copy, and Paste you should check out the somewhat related Change, Replace, & Substitute. It’s much shorted I promise, and I find “change” to be very useful.

  1. On macs the “fn” button is at the opposite corner of the keyboard as the “delete” key. Holding that down turns the “‘delete’, but actually backspace” key into an honest-to-goodness “delete” key.