How can I save a text block in visual mode to a file in Vim?

The title is very descriptive. Just in case, I will give an example:

START BLOCK1
something
END BLOCK1


START BLOCK2
something
somenthing...
END BLOCK2
  1. I select the BLOCK1 in visual mode
  2. I yank it by pressing y
  3. How can I save the yanked BLOCK1 to some other file?
26438 次浏览

There's probably a simpler way to do this, but what I would do is create a new buffer (or tab) and then paste it in with p. You can create a new buffer with :new or a new tab with :tabnew. You can write the buffer/tab to a file as normal with :w filename.

With the block is selected, you can :'<,'>w other-file, which will write only the selected block to other-file. Hitting : in visual mode should place '<,'> into the command line for you already, so you really only have to type :w other-file.

Select the text you wish to save, in either line visual or block visual mode, and

:w new.txt

That's what you type, but you won't actually see exactly what's above. When you press :, you'll go to the command line which will automatically get filled in with selection information. It'll look something like this:

:'<,'>

Just carry on typing the rest (w new.txt) to get

:'<,'>w new.txt

...and press enter.

Like @dronus mentioned in the comments, the :w !pbcopy suggestions does not copy correctly because it copies the entire line. If I want to copy only the url in a line, I will not be able to. Here's a line that you can add to your .vimrc file so that everytime you hit CTRL-C, the selected line in your vim will be copied to clipboard:

map <C-c> y:e ~/clipsongzboard<CR>P:w !pbcopy<CR><CR>:bdelete!<CR>

If you'd like to read details about what this does, you can read about this on my blog

Its the same implementation as what @rmeador suggested.

Similar to @songz's solution, I prefer do it like this using ":new"

vmap <C-c> y:new ~/.vimbuf<CR>VGp:x<CR>:!pbcopy < ~/.vimbuf<CR><CR>

Basing on @chenkaie's variant, works well for me:

let mapleader = "," let g:mapleader = "," vmap <leader>y y:new ~/.vbuf<CR>VGp:x<CR> nmap <leader>p :r ~/.vbuf<CR>

Vim get the visual selection and save to a file:

    function! Get_visual_selection()
"get the position of left start visual selection
let [line_start, column_start] = getpos("'<")[1:2]
"get the position of right end visual selection
let [line_end, column_end] = getpos("'>")[1:2]
"gotta catch them all.
let lines = getline(line_start, line_end)
if len(lines) == 0
return ''
endif
"edge cases and cleanup.
let lines[-1] = lines[-1][: column_end - 2]
let lines[0] = lines[0][column_start - 1:]
return join(lines, "\n")
endfunction


function Save_visually_selected_text_to_file()
let selected_text = Get_visual_selection()
call writefile(split(selected_text, "\n"), "/tmp/something.txt")
endfunction


"the c-u does a union of all lines in visual selection.
"this goes in the vimrc
vnoremap <F10> :<c-u>call Save_visually_selected_text_to_file()<cr>

In addition to selected answer above,

  • when using the mouse to select (1),

  • and the problem of only copying whole lines mentioned by the comment of @dronus to it, when just wanted to partly copy lines (2):

(1) At my Debian based DietPi (Raspberry PI)system, vim acts a little different like in the preferred solution above when using the mouse to enter and select 'VISUAL MODE' on my Ubuntu 16.04 work station. Then

  • y to yank it

but if I type ':' for command, it will not show up with the

'<,'>

where I can just simply add my

w new.txt

after it. So I just typed it by myself and it did work:

'<,'>w new.txt

and it copies the whole line(s) yanked content to my file 'new.txt', whereas '<,' seem to mean 'copy selected lines and '>' redirect it to the write command's referenced file.

(2) And to the problem of not pasting part of the line(s), like in @dronus comment mentioned, this solution (the selected one, first alternative) worked for me:

Edit the first file, yanking the text you want. Then open your second file from within vi (:e /path/to/other/file) and paste it (by typing p). Save it (like above ':w new.txt'.

It will then just copy the part of the lines marked up by mouse or 'y' with the cursors.

[EDIT] On my Ubuntu system: Sometimes selecting by mouse does NOT enter 'VISUAL MODE' in vim. Then the normal copy/paste can be selected using the context menu... I have not found the reason why Ubuntu changed it behaviour from a 'client acting behaviour' to a 'host' one (withUbuntu hosting the ssh bash window to my 'Client')...