Search code examples
vim

Vim: how to :source a part of the buffer


As everyone knows, we can :source current buffer by :so % .

But sometimes I want to :source just a part of the buffer, not the whole buffer. Say, I just added something to my .vimrc, and want to source that part, but I don't want to re-source all the rest stuff.

I tried select text and :so (actually :'<,'>so ) , but it reported that range is not allowed. So, how could this be done?

Of course I can save needed part to the temp file and source it, but it is clearly annoying.


Solution

  • Thanks to Ingo Karkat, I have taken his main idea and improved it. What I wanted to improve:

    • We have to use additional user-specified command :Execute instead of standard :so (ok, we can name user-specified command :So, anyway it's annoying to use new capitalized version of the command)
    • There is little side effect: register @z is corrupted after executing the command.

    With my script below, we can use :so {file} command as before, and we are also able to use it with range: :'<,'>so (which actually expands to :'<,'>Source)


    Here:

    " This script provides :Source command, a drop-in replacement for
    " built-in :source command, but this one also can take range and execute just
    " a part of the buffer.
    "
    
    
    " Sources given range of the buffer
    function! <SID>SourcePart(line1, line2)
       let tmp = @z
       silent exec a:line1.",".a:line2."yank z"
       let @z = substitute(@z, '\n\s*\\', '', 'g')
       @z
       let @z = tmp
    endfunction
    
    
    
    " if some argument is given, this command calls built-in command :source with
    " given arguments; otherwise calls function <SID>SourcePart() which sources
    " visually selected lines of the buffer.
    command! -nargs=? -bar -range Source if empty("<args>") | call <SID>SourcePart(<line1>, <line2>) | else | exec "so <args>" | endif
    
    
    
    " in order to achieve _real_ drop-in replacement, I like to abbreviate
    " existing :so[urce] command to the new one.
    "
    " So, we can call :so %  just as before, and we are also call  '<,'>so
    
    cnoreabbr so     Source
    cnoreabbr sou    Source
    cnoreabbr sour   Source
    cnoreabbr sourc  Source
    cnoreabbr source Source