3

I'm creating a Vim script and a critical part of it is duplicating the selected lines. To duplicate lines, I have this mapping which works as intended:

vnoremap <Leader>d :copy '><CR> 

But, when inside a function/script, the behavior of copy seems different:

function Foo() copy '> endfunction 

Sample Selected Lines

x = 'alpha' y = 'bravo' z = 'charlie' 

Expected Result

x = 'alpha' y = 'bravo' z = 'charlie' x = 'alpha' y = 'bravo' z = 'charlie' 

Actual Result (lines seem to be copied in reverse order)

x = 'alpha' y = 'bravo' z = 'charlie' z = 'charlie' y = 'bravo' x = 'alpha' 

Likewise, running the copy command manually against the selected lines works as expected: :'<,'>copy '>

Am I missing something? Are there better ways to duplicate selected lines programmatically? Thanks

1
  • 1
    Welcome to Vi and Vim! Commented Apr 17, 2022 at 3:32

1 Answer 1

3

I figured out the culprit. Thanks to Tim Pope's comment on my posted issue and the related answer here.

copy here is executed once per line selection which is not the intended behavior (i.e. the reverse order in the duplicated lines):

function Foo() copy '> endfunction 

We want to execute the '<,'>copy '> inside the script instead. But, this will duplicate the N selected lines N times:

function Foo() '<,'>copy '> endfunction 

Effectively, we want to duplicate the N selected lines once only. There are 2 options:

  • append range at the function definition:
    function Foo() range '<,'>copy '> endfunction 
  • prepend the command with <C-U> to clear the selection before calling the function:
    function Foo() '<,'>copy '> endfunction xnoremap <Leader>r :<C-U>call Foo()<CR> 

Both work as intended!

2
  • 2
    Great answer! In the function ... range, you should actually use execute a:firstline . "," . a:lastline . "copy '>" in the body, which actually works with the range that was passed, instead of the range of the last visual selection. That would make :1,5call Foo() or :%call Foo() work. See also this answer which expands on range functions a bit. Commented Apr 17, 2022 at 3:33
  • 1
    Right, that would be a nice improvement to handle various scenarios. Thanks! Commented Apr 18, 2022 at 0:03

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.