5

I have 2 pieces of text, what is a proper way to switch those pieces of text. around e.g. I have this:

This is one piece of text.
Here is another sentence.

And I want to switch around the 3 first words in these sentences, so it becomes:

Here is another piece of text.
This is one sentence.

Another variant of a similar thing:

 <paragraph>Some text here</paragraph>
 <paragraph><note>And something else here</note></paragraph>

And I'd want to switch the innermost text so it becomes:

 <paragraph>And something else here</paragraph>
 <paragraph><note>Some text here</note></paragraph>

3 Answers 3

4

There are a number of ways to do this, but I would say the most useful & generic way is to use visual mode (:help visual-mode).

In your first example:

This is one piece of text.
Here is another sentence.

I would put the cursor on the first T (in This), start visual mode with v, and select the text you want to replace by using l (that's a lower case L) or the arrow key, and select the text up to and including the e in one).
You can then delete the text with d.

Note that d doesn't actually delete the text, it copies the text to the unnamed register (""), and then removes it from the buffer. So it's more like "cut" (Ctrl+x) as used in many applications, and not delete (also see :help "").

Armed with this information, we can now go to the second line, start visual mode with v again, and select the text we want to replace (in this case, Here is another), and press p.
The p is for "put", which is Vi-speak for "paste". Because we've selected some text with visual mode, it will replace this text. But again, this text is not lost: it's put in the unnamed register (replacing the text that was there before).

We can now go to the start of the first line, and press P, this will put the text from the second line at the cursor position.

p and P both "put" (paste) text, the difference is that the former puts the text after the cursor, while the latter puts it before this cursor. I often use the wrong one by accident: remember that you can use u to undo and then use the correct one :-)

I hope it will be obvious how to use this technique in your second example :-)


Bonus tip: The motion picture

Above I told you to select the text with l or the arrow keys, but there are better ways!

For example, we could also have used v3wd. The v starts visual mode, and 3w selects the next 3 words, and the d deletes it. This is obviously a lot quicker.

In fact, you don't even need visual mode, just using 3wd will work the same. I personally prefer to start visual mode, because you can easily see what you're about to delete, and adjust if required.


Bonus tip 2: The wrath of motions

In your second example:

<paragraph>And something else here</paragraph>
<paragraph><note>Some text here</note></paragraph>

I would put the cursor on the A of And, and type t<. This put the cursor just before the first occurrence <; very useful!
There's also f, which puts the cursor on the first occurrence of what you find, and you could also use 2t< to put the cursor before the second occurrence of <.

See :help cursor-motions for more information about cursor motions. Note that you could also use the mouse to do all of this if you've enable it, but that's of course not the true Vi way ;-)


Bonus tip 3: The search for registers

The d and p use the unnamed register by default, but you can specify a register; for example, "ad would delete ("cut') the text to the a register (leaving the unnamed " register alone), and "ap would put ("paste") from this register. This can be quite useful in a number of scenarios.

See :help registers.

2
  • 1
    I find this to be the most intuitive way, personally. I added a small mapping in my .vimrc so that after deleting the first, I can highlight the second and hit <C-X> to exchange:xnoremap <C-x> <Esc>`.``gvP``P
    – Matt Boehm
    Feb 23, 2015 at 16:31
  • Nice write-up. A couple errors in tip 1 though. 3wd is incorrect, should be 3dw or d3w. v3wd is not the same as 3dw. Doing d after the visual select will cut off an extra letter (the beginning of the 4th word). May 23, 2020 at 1:03
5

@Carpetsmoker has given a very nice and thorough answer with good explanations. However, in this particular case, I think the best solution is to use the basic delete three words command, that is, d3w. The words can then be inserted at the desired spot with p or P. A detailed description:

  1. Put cursor on first letter of first word in first sentence
  2. Do d3w
  3. Put cursor on first letter of first word in second sentence
  4. Do Pd3w
  5. Go back to beginning of first sentence
  6. Do P
2
  • Yeah, the visual mode in my answer is entirely superfluous; you don't need it as such (I briefly mentioned this in my answer, but I didn't want to make it too long), but I am personally not smart enough to use vi/Vim motions flawlessly :-) IMHO visual mode makes things a lot easier, and because I make less mistakes, also makes it more efficient :-) Feb 22, 2015 at 17:30
  • I agree the visual mode is very useful and that it often makes things easier and clearer. Btw: I just noticed that my answer was covered by your first bonus tip. But I think it should be the first thing to mention, and deserves more than the bonus tip spot. :) Feb 22, 2015 at 18:18
5

Another way would be to use the vim-exchange plugin. This plugin provides the cx command.

This can be used by going to the start of the first line, and pressing cx3w; the 3w in this case represents the 3 words you want to replace.
This text is then highlighted, you can now move the cursor and use cx3w again, which will swap the text.

For your second example, you can put the cursor on the S in Some, use cx3t; then go to the second line, put the cursor on the A in And, and use cx3t again.

Or, when you have the vim-repeat plugin installed: cx3wj.

4
  • It seems this plugin is written by tommcdo :-) ... It's not clear to me how to use the vim-repeat plugin by the way; is this a separate way to do this? Or something that's to be used in combination with vim-exchange? Feb 22, 2015 at 17:21
  • Exchange.vim doesn't actually require repeat.vim :)
    – tommcdo
    Feb 22, 2015 at 17:27
  • vim-repeat is a plugin to repeat certain commands with the dot .. Other plugins can use vim-repeat to repeat their own functionality with .. Feb 22, 2015 at 17:59
  • There seems to be a common misconception that repeat.vim is required for repeating to work on all custom operators. However, it is only needed for operators that work outside of the simple operator-motion paradigm, such as surround.vim and lion.vim. Both of these accept additional characters after defining the motion. Without hooking into retreat.vim, typing . after using these operators would require re-typing the additional characters as well.
    – tommcdo
    Feb 23, 2015 at 1:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.