Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

In vim, I often find myself repeating the same steps to copy a section before making changes to it:

  1. V to start Visual mode linewise
  2. j until I have selected the section I want to copy
  3. y to yank the selection
  4. j to scroll down to the last line of the text I just selected
  5. p to copy the yanked section below the current line
  6. O to start a new blank line above the copied text
  7. ESC to leave insert mode

Is there a more efficient way to accomplish this (or any part of it)? In particular, it seems like there should be a better way to put text below the selection you just selected, rather than scrolling down to select it, yanking it, and scrolling down to the bottom again.

share|improve this question
add comment

2 Answers

up vote 2 down vote accepted

The real bottleneck, here seems to be all the jjjj… that you are doing. The supposed superiority of hjkl over the arrow keys is cited so often that people tend to forget the immense value of Vim's motions and text-objects over both tedious methods.

Supposing you are on the first line of a paragraph as defined by Vim (text between blank lines), y'}P should yank the whole paragraph including the blank line that follows and paste it above the current line.

some text above 

[l]orem ipsum dolor sit amet
ipsum lorem dolor sit amet
lorem dolor ipsum sit amet
lorem ipsum sit dolor amet
lorem ipsum dolor amet sit

some text below

y'}P

some text above

[l]orem ipsum dolor sit amet
ipsum lorem dolor sit amet
lorem dolor ipsum sit amet
lorem ipsum sit dolor amet
lorem ipsum dolor amet sit

lorem ipsum dolor sit amet
ipsum lorem dolor sit amet
lorem dolor ipsum sit amet
lorem ipsum sit dolor amet
lorem ipsum dolor amet sit

some text below

v}yP should work too, in a more comfortable way.

If your block is not a "paragraph", there's probably a way to define the selection with a motion instead of jjj. Something like V/it$<cr>.

edit

Here is another variant that places the copy below the original: y'}'}p.

edit

I think that the most generic way to shorten the whole process is to extend the visual selection either:

  • with a search motion if you can identify a "hook" on the last line of the block you want to duplicate (V/foo<CR>)

  • or a count (V5j).

Once the selection is done, you can:

  • yank (y),

  • move to the end of the visual selection ('> or 5j but '> is more generic),

  • open a new line (o),

  • leave insert mode (<Esc>),

  • paste (p)

This method is probably the most generic but that's still a lot of typing. That's where mappings come to the rescue:

vnoremap <F9> y'>o<Esc>p

The idea, here, is to separate the contextual from the generic:

  • the contextual part is when you define the block to duplicate, because there's no way to predict what you want to duplicate I leave this part to your discretion but I hope you'll use a better method than jjjjjj…

  • the generic part is everything that follows the selection, done here with a simple mapping.

The whole process is now reduced to V5j<F9> which is as quick as you can get.

share|improve this answer
    
I'll look into those. It's often a method in Python I'm going for, but sometimes more arbitrary blocks of text. –  jrdioko Oct 12 '12 at 20:53
    
These options won't wind up with your cursor in between the two sections though, it seems. You still have to move down after the put. –  jrdioko Oct 12 '12 at 21:49
    
Yes but that's not what the OP is trying to achieve. He wants to duplicate a block of text to modify it. Ending up with the cursor between the two blocks would be counterproductive because he would need to move the cursor again to even begin to edit the copy. With y'}P, the cursor ends up on the first line of the copy, ready for further editing. –  romainl Oct 13 '12 at 6:33
    
Yes it is, I am the OP :) Sorry for the confusion, what I'm trying to do is copy a piece of text, then begin editing the bottom version (that's why I wanted the cursor in the middle). It looks like your edit does accomplish that for the "paragraph" case. Is there a way to do that with an arbitrary visual mode selection? –  jrdioko Oct 14 '12 at 0:54
1  
:help motion.txt will blow your mind. –  romainl Oct 14 '12 at 21:15
show 3 more comments

If I understand, your goal is to have essentially two copies of some chunk of text one right after the other. In that case, try this:

  1. Shift-V
  2. j to select region
  3. y to yank
  4. Shift-P to put above your current location
  5. When you do the put, it will tell you how many lines it added. Type this number then hit j
  6. Shift-O

I realize that all this does is remove the scrolling, but for any sizeable amount of text, that will be the longest bit of the evolution and the most prone to over/under shooting the right location.

share|improve this answer
    
Yes, I'm just trying to copy a chunk of text I want to use as the base for something else. That Shift-P was the missing piece, I think (you don't even need your step 5). I was copying below, scrolling down, and editing the copy, but I guess there's no reason I can't copy above, avoid scrolling, and edit the original. Thanks. –  jrdioko Oct 12 '12 at 19:22
    
Oh nevermind maybe, Shift-P doesn't move the cursor like I thought it would. –  jrdioko Oct 12 '12 at 21:45
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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