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.
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 end
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?
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
Yank (Copy) works exactly the same as delete except it leaves the text in place
and you use
y instead of
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.
d is the key to _d_eleting lines. As noted above, you can just whack it twice (
to affect just the current line. If you want to delete the current line and the
4 after it you type
Deleting parts of lines.
Deleting to the end of the line
D will delete everything from your cursor to the end of the
$ means end of line you can combine
d with the instruction to
move to the end of the line:
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
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.
<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
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
<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
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,
n is a way to move your cursor, and I said you can combine movement
with these verbs.
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
y is the key to copying things. Like Delete you can just whack it twice (
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:
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
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
⌘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
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
But Vim a special register just for interacting with the system clipboard. It’s
* 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
"* Next add
whatever you would normally do for the
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
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.
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.
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.
- 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. ↩