Practical Vim< /a> vit Practical Vim< /a> Note that the styling for a Visual selection is the... development I thought I knew Vim, but Practical" name="description"/>
Tải bản đầy đủ - 0 (trang)
Tip 59. Delete, Yank, and Put with Vim's Unnamed Register

Tip 59. Delete, Yank, and Put with Vim's Unnamed Register

Tải bản đầy đủ - 0trang

Chapter 10. Copy and Paste



• 142



Transposing Characters

I consistently misspell some words. Over time, I may notice that I habitually

mistype a certain word, and then I can train myself out of it. But some spelling

mistakes are more haphazard. The most common typing error that I make is

to get two characters in the wrong order. Vim makes it easy to fix such mistakes.

Suppose that we’re typing out the title of this book when we make such a

transposition error:

Keystrokes



Buffer Contents



{start}



Practica lvim



F␣



Practica lvim



x



Practicalvim



p



Practical vim



Here we’ve typed the space too soon, but it’s easily mended. The F␣ command

places our cursor on the first of the two characters that we want to swap (see

Tip 49, on page 114). The x command cuts the character under the cursor,

placing a copy of it in the unnamed register. Then the p command pastes the

contents of the unnamed register after the cursor position.

Taken together, the xp commands can be considered as “Transpose the next

two characters.”



Transposing Lines

We can just as easily transpose the order of two lines of text. Instead of using

the x command to cut the current character, we can use the dd command,

which cuts the current line, placing it into the unnamed register:

Keystrokes



Buffer Contents



{start}



2) line two

1) line one

3) line three



dd



1) line one

3) line three



p



1) line one

2) line two

3) line three



The p command knows that this time we’re dealing with a line-wise chunk

of text, so it does the thing we would expect: it pastes the contents of the



www.it-ebooks.info



report erratum • discuss



Delete, Yank, and Put with Vim’s Unnamed Register



• 143



unnamed register after the current line. Remember, when we pressed xp in

the previous example, the p command pasted after the current character.

The ddp sequence could be considered to stand for “Transpose the order of

this line and its successor.”



Duplicating Lines

If we want to create a new line of text that’s broadly similar to another line

but with one or two small differences, we can give ourselves a head start by

duplicating a line and using it as a template. In Vim, a line-wise yank followed

by a put operation does the trick:

Keystrokes



Buffer Contents



{start}



1) line one

2) line two



yyp



1) line one

2) line two

2) line two



Note the similarities between these two sequences, ddp and yyp . The first does

a line-wise cut and paste, which effectively transposes the order of two lines.

The second sequence does a line-wise copy and paste, which effectively

duplicates a line.



Oops! I Clobbered My Yank

So far, Vim’s delete, yank, and put operations are looking quite intuitive. They

make common tasks trivially easy to perform. Now let’s look at a scenario

where things don’t work out quite so smoothly. Start off with this sample:

copy_and_paste/collection.js

collection = getCollection();

process(somethingInTheWay, target);



We’re going to copy collection into the unnamed register and then replace

somethingInTheWay with the word that we’ve just copied. Table 15, Copy and

Paste—First Attempt, on page 144 shows a first attempt.

To begin with, our cursor is already on the word we want to copy, so we can

get it into the unnamed register by typing yiw .

Next we move our cursor to the place where we want to paste our collection,

but before we can put it there we’ll have to clear a space for it. So we run diw

to delete the word somethingInTheWay.



www.it-ebooks.info



report erratum • discuss



Chapter 10. Copy and Paste



Keystrokes



Buffer Contents



yiw



collection = getCollection();

process(somethingInTheWay, target);



jww



collection = getCollection();

process(somethingInTheWay, target);



diw



collection = getCollection();

process(, target);



P



collection = getCollection();

process(somethingInTheWay, target);



• 144



Table 15—Copy and Paste—First Attempt

Now we can hit the P key to paste the contents of our unnamed register in

front of the cursor. But instead of pasting the word collection, which we yanked

earlier, we get the word somethingInTheWay. What’s going on?

The diw command doesn’t just delete the word: it also copies it into the

unnamed register. Or to rephrase that using more familiar terminology

— diw cuts the word. (See Vim's Terminology Versus the World, on page 145, for

a discussion).

It’s obvious now what we did wrong. When we ran the diw command, it overwrote the contents of the unnamed register. That’s why when we pressed P ,

we got back the word we just deleted rather than the word we yanked earlier.

To solve this problem, we’ll have to get a deeper understanding of how Vim’s

registers work.



Tip 60



Grok Vim’s Registers

Rather than using a single clipboard for all cut, copy, and paste operations,

Vim provides multiple registers. When we use the delete, yank, and put commands, we can specify which register we want to interact with.



Addressing a Register

The delete, yank, and put commands all interact with one of Vim’s registers.

We can specify which register we want to use by prefixing the command with

"{register} . If we don’t specify a register, then Vim will use the unnamed

register.



www.it-ebooks.info



report erratum • discuss



Grok Vim’s Registers



• 145



Vim’s Terminology Versus the World

The cut, copy, and paste terminology is universally understood, and these operations

are available across most desktop software programs and operating systems. Vim

provides these features too, but it uses different terminology: delete, yank, and put.

Vim’s put command is effectively identical to the paste operation. Fortunately, both

words begin with the letter p, so the mnemonic for the key command works

whichever terminology we use.

Vim’s yank command is equivalent to the copy operation. Historically, the c command

was already assigned to the change operation, so vi’s authors were pushed to come

up with an alternative name. The y key was available, so the copy operation became

the yank command.

Vim’s delete command is equivalent to the standard cut operation. That is, it copies

the specified text into a register and then removes it from the document. Understanding this is key to avoiding the common pitfall outlined in Oops! I Clobbered My Yank,

on page 143.

You might be wondering what Vim’s equivalent is for really deleting text—that is, how

can you remove text from the document and not copy it into any registers? Vim’s

answer is a special register called the black hole, from which nothing returns. The

black hole register is addressed by the _ symbol (see :h quote_ ), so "_d{motion} performs

a true deletion.



For example, if we wanted to yank the current word into register a, we could

run "ayiw . Or if we wanted to cut the current line into register b, we could run

"bdd . Then we could paste the word from register a by typing "ap , or we could

paste the line from register b by typing "bp .

In addition to the Normal mode commands, Vim also provides Ex commands

for delete, yank, and put operations. We could cut the current line into register

c by running :delete c, and then we could paste it below the current line with

the :put c command. These may seem verbose in comparison with the Normal

mode commands, but they’re useful in combination with other Ex commands

and in Vim scripts. For example, Tip 99, on page 240, shows how :yank can be

used with the :global command.



The Unnamed Register ("")

If we don’t specify which register we want to interact with, then Vim will use

the unnamed register, which is addressed by the " symbol (see :h quote_quote ).

To address this register explicitly, we have to use two double quote marks:

for example, ""p , which is effectively equivalent to p by itself.



www.it-ebooks.info



report erratum • discuss



Chapter 10. Copy and Paste



• 146



The x , s , d{motion} , c{motion} , and y{motion} commands (and their uppercase

equivalents) all set the contents of the unnamed register. In each case, we

can prefix "{register} to specify another register, but the unnamed register

is the default. The fact that it’s so easy to overwrite the contents of the

unnamed register can cause problems if we’re not careful.

Consider again the example in Oops! I Clobbered My Yank, on page 143. We

start off by yanking some text (the word “collection”) with the intention of

pasting it elsewhere. Before we can paste it, we have to clear a space by

deleting some text that is in our way, which overwrites the contents of the

unnamed register. When we use the p command, we get back the text that

we just deleted, rather than getting the text that we yanked previously.

Vim’s choice of terminology is unfortunate. The x and d{motion} commands

are usually referred to as “delete” commands. This is a misnomer. It’s better

to think of them as “cut” commands. The unnamed register often doesn’t

contain the text that I expected to find there, but luckily, the yank register

(which we’ll meet next) is more dependable.



The Yank Register ("0)

When we use the y{motion} command, the specified text is copied not only

into the unnamed register but also into the yank register, which is addressed

by the 0 symbol (see :h quote0 ).

As the name suggests, the yank register is set only when we use the y{motion}

command. To put it another way: it’s not set by the x , s , c{motion} , and

d{motion} commands. If we yank some text, we can be sure that it will stick

around in register 0 until we explicitly overwrite it by yanking something else.

The yank register is reliable, whereas the unnamed register is volatile.

We can use the yank register to solve our problem from Oops! I Clobbered My

Yank, on page 143:

Keystrokes



Buffer Contents



yiw



collection = getCollection();

process(somethingInTheWay, target);



jww



collection = getCollection();

process(somethingInTheWay, target);



diw



collection = getCollection();

process(, target);



"0P



collection = getCollection();

process(collection, target);



www.it-ebooks.info



report erratum • discuss



Grok Vim’s Registers



• 147



The diw command still overwrites the unnamed register, but it leaves the yank

register untouched. We can safely paste from the yank register by pressing

"0P , and Vim gives us the text that we want.

If we inspect the contents of the unnamed and yank registers, we’ll see that

they contain the text that we deleted and yanked, respectively:









:reg "0

--- Registers --"" somethingInTheWay

"0 collection



The Named Registers ("a–"z)

Vim has one named register for each letter of the alphabet (see :h quote_alpha ).

That means that we can cut ( "ad{motion} ), copy ( "ay{motion} ), or paste ( "ap )

up to twenty-six pieces of text.

We could use a named register to solve our problem from Oops! I Clobbered

My Yank, on page 143:

Keystrokes



Buffer Contents



"ayiw



collection = getCollection();

process(somethingInTheWay, target);



jww



collection = getCollection();

process(somethingInTheWay, target);



diw



collection = getCollection();

process(, target);



"aP



collection = getCollection();

process(collection, target);



Using a named register requires extra keystrokes, so for a simple example

like this we’re better off using the yank register ("0). Named registers can

become really useful when we’ve got one or more pieces of text that we want

to paste in several places.

When we address a named register with a lowercase letter, it overwrites the

specified register, whereas when we use an uppercase letter, it appends to

the specified register. Skip ahead to Tip 99, on page 240, to see a demonstration

of appending to a register.



The Black Hole Register ("_)

The black hole register is a place from which nothing returns. It’s addressed

by the underscore symbol (see :h quote_ ). If we run the command "_d{motion} ,

then Vim deletes the specified text without saving a copy of it. This can be



www.it-ebooks.info



report erratum • discuss



Chapter 10. Copy and Paste



• 148



useful if we want to delete text without overwriting the contents of the

unnamed register.

We could use the black hole register to solve our problem from Oops! I Clobbered My Yank, on page 143:

Keystrokes



Buffer Contents



yiw



collection = getCollection();

process(somethingInTheWay, target);



jww



collection = getCollection();

process(somethingInTheWay, target);



"_diw



collection = getCollection();

process(, target);



P



collection = getCollection();

process(collection, target);



The System Clipboard ("+) and Selection ("*) Registers

All of the registers that we’ve discussed so far are internal to Vim. If we want

to copy some text from inside of Vim and paste it into an external program

(or vice versa), then we have to use one of the system clipboards.

Vim’s plus register references the system clipboard and is addressed by the

+ symbol (see :h quote+ ).

If we use the cut or copy command to capture text in an external application,

then we can paste it inside Vim using "+p command (or + from the Insert

mode). Conversely, if we prefix Vim’s yank or delete commands with "+ , the

specified text will be captured in the system clipboard. That means we can

easily paste it inside other applications.

The X11 windowing system has a second kind of clipboard called the primary.

This represents the most recently selected text, and we can use the middle

mouse button (if we have one) to paste from it. Vim’s quotestar register maps

to the primary clipboard and is addressed by the * symbol (:h quotestar ).

Keystrokes



Buffer Contents



"+



The X11 clipboard, used with cut, copy, and paste



"*



The X11 primary, used with middle mouse button



In Windows and Mac OS X, there is no primary clipboard, so we can use the

"+ and "* registers interchangeably: they both represent the system clipboard.



www.it-ebooks.info



report erratum • discuss



Replace a Visual Selection with a Register



• 149



Vim can be compiled with or without support for X11 clipboard integration.

To find out whether your version of Vim has the feature enabled, run the

:version command and look for xterm_clipboard. If it’s prefixed with a minus sign,

then your version of Vim does not support this feature. A plus sign means

that the feature is available.



The Expression Register ("=)

Vim’s registers can be thought of simply as containers that hold a block of

text. The expression register, referenced by the = symbol (:h quote= ), is an

exception. When we fetch the contents of the expression register, Vim drops

into Command-Line mode, showing an = prompt. We can enter a Vim script

expression and then press to execute it. If the expression returns a string

(or a value that can be easily coerced into a string), then Vim uses it.

For examples of the expression register in action, check out Tip 16, on page

31, Tip 95, on page 230, Tip 94, on page 229, and Tip 70, on page 174.



More Registers

We can set the contents of the named, unnamed, and yank registers explicitly

using the delete and yank commands. In addition, Vim provides a handful of

registers whose values are set implicitly. These are known collectively as the

read-only registers (:h quote. ). The following table summarizes them:

Register



Contents



"%



Name of the current file



"#



Name of the alternate file



".



Last inserted text



":



Last Ex command



"/



Last search pattern



Technically, the "/ register is not read-only—it can be set explicitly using the

:let command (see :h quote/ )—but it’s included in this table for convenience.



Tip 61



Replace a Visual Selection with a Register

When used from Visual mode, Vim’s put command has some unusual qualities.

We’ll find out how these can be exploited in this tip.



www.it-ebooks.info



report erratum • discuss



Chapter 10. Copy and Paste



• 150



When we use the p command in Visual mode, Vim replaces the selection with

the contents of the specified register (see :h v_p ). We can exploit this feature

to solve our problem from Oops! I Clobbered My Yank, on page 143:

Keystrokes



Buffer Contents



yiw



collection = getCollection();

process(somethingInTheWay, target);



jww



collection = getCollection();

process(somethingInTheWay, target);



ve



collection = getCollection();

process(somethingInTheWay, target);



p



collection = getCollection();

process(collection, target);



For this particular problem, this is my favorite solution. We can get away with

using the unnamed register for both the yank and put operations because

there’s no delete step. Instead, we combine the delete and put operations into

a single step that replaces the selection.

It’s important to understand that this technique has a side effect. Try pressing

u to undo the last change. Now press gv to reselect the last visual selection

and then press the p key again. What happens? Apparently nothing!

To make it work this time, we’d have to press "0p to replace the visual selection

with the contents of the yank register. We got away with using p the first time

because the unnamed register happened to contain the text that we wanted

to use. The second time around, the unnamed register contains the text that

was overwritten.

To illustrate how strange this is, let’s consider an imaginary API for the

standard cut, copy, and paste model. This API has methods called setClipboard()

and getClipboard(). The cut and copy operations both call setClipboard(), while the

paste operation calls getClipboard(). When we use Vim’s p command in Visual

mode, it does both: it gets the contents of the unnamed register, and it sets

the contents of the unnamed register.

Think of it this way: the visual selection in the document swaps places with

the text in the register. Is it a feature? Is it a bug? You decide!



Swap Two Words

We can exploit this quirk in Vim’s visual put behavior. Let’s say that we want

to swap the order of two words in this sentence to make it read “fish and

chips”:



www.it-ebooks.info



report erratum • discuss



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tip 59. Delete, Yank, and Put with Vim's Unnamed Register

Tải bản đầy đủ ngay(0 tr)

×