I want to :r[ead] a file into current buffer, and the file should be picked with the browser (that opens automatically e.g. when trying to :e[dit] a directory.

:e ~/.vim/ opens a file browser in the ~/.vim/ directory, but :r ~/.vim/ just complains about ~/.vim not being a file.

:h browse seems to imply that :bro r ~/.vim/ should open a bowser to find a file to read, but it too doesn't.

I'm running

VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Feb 9 2016 10:20:47)

Included patches: 1-1294

Compiled by Arch Linux

  • 1
    :browse :r ~/.vim works just fine for me. Feb 24 '16 at 21:59
  • 2
    Huh. For me it returns i.imgur.com/V8Yj1t7.png
    – lindhe
    Feb 24 '16 at 22:09
  • 1
    @ChristianBrabandt On Linux, it's only available when used with the GUI.
    – muru
    Feb 25 '16 at 1:22
  • I thought we are talking about the gui here. Feb 25 '16 at 6:49

When I try your command :bro r ~/.vim/, I have the following error:

E338: Sorry, no file browser in console mode

There may be a native and simpler way, but assuming you use the default file browser netrw, then you could try the following code:

augroup custom_netrw
    autocmd FileType netrw nnoremap <buffer> e :<C-U>call <SID>ReadNetrw()<CR>
augroup END

function! s:GetFileNames(first, last) abort
    " Grab lines between first and last
    let l:files = getline(a:first, a:last)

    " If some of them are from the banner, remove them
    call filter(l:files, 'v:val !~# "^\" "')
    " If some of them are a directory, an executable, a fifo or a socket
    " they end up with one of the symbols: /*|=
    " Remove them
    call filter(l:files, 'v:val !~# "[/*|=]$"')
    " Remove the text after the @ symbol (link):
    call map(l:files, "substitute(v:val, '@\\t.*$', '', '')")

    " Prepend the path of the current directory in front of each filename
    return map(l:files, 'b:netrw_curdir . "/" . v:val')

function! s:ReadNetrw() abort
    " Get the name of the file on the current line, and on following ones if
    " a count was hit before the mapping (i.e. if v:count1 != 1)
    let l:files = s:GetFileNames(line('.'), line('.') - 1 + v:count1)

    " Go back to alternate buffer before reading

    for i in range(len(l:files))
        " Read each file
        execute 'read ' . l:files[i]
        " After each insertion, move the cursor at the end of it

It installs a buffer-local mapping on the e key (r seems already taken by netrw to reverse the sort order) which calls the function ReadNetrw().

If you open netrw with :e ~/.vim/ and then hit e on a file, its contents should be read in the alternate buffer (which should be the buffer from which you opened netrw).
The mapping accepts a count, meaning that if you hit 3e, it should read the file under the cursor as well as the 2 following ones.

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.