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?
You can copy the text with the mouse if you do not have the mouse enabled (e.g.
set mouse=), and enable
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 :-)
You have several alternatives.
TOhtmlcommand to let Vim generate an HTML file, which includes the line numbers, and then copy and paste from that file.
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
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 (
+clipboard, instead of
:redir @a :silent! :'<,'>number :redir END
: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,
:redirallows 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.
Why so complicated? The easy way to to this is with the
Disclaimer: before you start messing with files with the
teecommand make an alias in your
.profilefor the command:
alias tee="tee -a"
teeto append to rather than obliterate the file. What
teedoes specifically is take
stdoutand redirects it to files, similar to
echo some text > file.
But it works with what is produced on the terminal.
In order to use
tee properly we need to get some
stdout and that is where
grep comes in.
What you want to do is
grep (find) the text you want to produce which by default will put the text as
stdout. You can also add lines before or after the line you want with
-C flags. Also, to add line number you can add the
-n flag. So if you add
-A5 for example, you will get the line you grep for plus 5 lines after that. Similarly with
-B5 but in this case you get the line you grep for plus 5 lines before what you grep for.
-C5 you get 5 lines before and after meaning 10 lines plus what you grep for. The
-n flag gets you your line numbers.
grep -n[-ABC][num] "search line" | tee [-a, unless you alias it already] [file]
This command is a lot more simple. You see everything on the screen.
The only drawback (if it is a drawback) is that when
grep adds line numbers, it does so with a colon and each line after that gets a dash like this:
33: text.... 34- text.... 35- text....
However seeing how you are injecting line numbers to begin with, this is a good visual clue, especially if you have line numbers enabled in your text editor.
It could get real confusing otherwise.