2

I would like to copy several lines with line numbers; the text from set number isn't copied. Is there any way to do this?

  • 1
    When Vim runs within tmux (and possibly other tools), you could achieve this by using the copy mode; assuming you have the set numbers on. – Rolf May 29 at 6:32
2

You have several alternatives.

  1. Use the TOhtml command to let Vim generate an HTML file, which includes the line numbers, and then copy and paste from that file.

  2. Replace each line by its line number plus its content, so you can copy it with the line number. This can be done by visually selecting the lines, and using the following substitute command:

    :s/^/\=printf("%2d ", line('.'))/ 
    

    You obviously want to undo this replace after copying using e.g. undo or :s/^\d\+ //

  3. Create your own command to take care of copying the desired text together with the line numbers. Something like this should work:

    fu! s:yank_number(first, last) 
        let start = a:first 
        let l = [] 
        while start <= a:last 
            let l = add(l, printf("%" . len(a:last) . "d %s", start, " " . getline(start))) 
            let start += 1
        endwhile 
        return join(l, "\n") . "\n" 
    endfu 
    
    command! -nargs=0 -range Yank :let @+ = s:yank_number(<line1>, <line2>) 
    

    Now select your text and enter :Yank, which will copy the range to the +-register (which should correspond to your system's clipboard, if your Vim was compiled with clipboard functionality (:help should output +clipboard, instead of -clipboard).

  4. Use :redir:

    :redir @a 
    :silent! :'<,'>number
    :redir END 
    

    or

    :redir @a | silent! :'<,'>number | redir END
    

    to pull the numbered lines into register "a". This can be wrapped into a mapping:

    :vnoremap <f4> :<home>redir @a<bar>silent! <end>number<bar>redir END<cr> 
    

    assuming you always want to trump the same register. If you use it frequently, you might designate a preferred register such as "n" for "(n)umbered" and then only use it for that purpose. Alternatively, :redir allows you to redirect to other sinks if you prefer.


DISCLAIMER: The above options have been created from the Vim mailing list thread, using:

If you are one of the above authors, and would like to take credit for it, please let me know, and I will delete the question and answer so that you can re-create it.

  • 1
    You can use execute() instead of :redir to not clobber a register: :echo execute("'<,'>#"). I've also found some weird bugs with :redir over the years, and generally try to avoid it. – Martin Tournoij May 15 at 22:02
  • execute() did not exists back when that question was initially asked – Christian Brabandt May 16 at 6:35
  • Hi @MartinTournoij .. I use redir to load the clipboard with a command's output pretty often. I don't recall ever having problems. OTOH I've only been doing this for, oh, the last 3 years or so so perhaps there were issues but they've since been fixed. Have you had any problems that you recall in that same rough time frame? (Out of curiosity primarily. Thanks.) – B Layer Jul 3 at 5:53
1

You can copy the text with the mouse if you do not have the mouse enabled (e.g. set mouse=), and enable number.

This will work in any terminal, and also seems to work in the GTK3 version of gvim (but may not work in all gvim versions).

From the perspective of the terminal there is no difference between the number column on the left and the buffer contents; it's all just text. This can be either a good or bad thing, depending on what you want. If you want to copy the number column then it's a good thing :-)

  • 1
    with mouse enabled, I think one can use shift + mouse click to copy. However, this might be problematic, if you have vertical split windows open. – Christian Brabandt May 16 at 7:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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