If I have a couple of lines of vimscript that I want to test before putting in my vimrc, is it possible to visually select, then source them?

I have tried

  • make visual selection v, then motions to make selection etc, then
  • :'<,'>so

But vim gives an error

no range allowed


:'<,'>w | so


Use ! to write partial buffer

How can I source visually selected vimscript?


On the command line hit <C-u> then type @* and enter.

<C-u> will delete the visual range '<,'> that has been automatically inserted if some text is visually selected.

:@* will execute the content of the * register which contains whatever is visually selected at the moment.

Even if the text that is selected / highlighted is in your web browser (firefox, chrome, ...), it will work, the * register will allow you to access it directly in vim.

If your text is selected in a vim buffer, another solution is to copy it in a named register, for example the a register by typing "ay.

Then, on the command line, type : <C-r>a and enter.
Ctrl + r will give you a sort of prompt represented by the character " (for more information read :h c_Ctrl-r).
At this new prompt, if you give the name of a register, its content will be inserted on the command line, where you'll be able to edit it before execution.

Besides if you copy some text without specifying a register, it will be accessible from the unnamed register ".

So suppose you've got a line of vimscript in a file and want to source it quickly, you can copy it with Y, then source it on the command line with : :<C-r>" and enter.

Finally, if you use this last solution, there's just a problem you must be aware of.
If you see a strange character on the command line like this ^M, it's the caret notation of the carriage return. You should delete it, otherwise you'll probably get an error.

In summary, you :

  1. copy your line of vimscript with Y
  2. switch to command mode with :
  3. hit <C-r> to enter the registers prompt
  4. type " to call the unnamed register
  5. hit backspace to delete the ^M character
  6. and hit enter.
  • 1
    Sweet! :D works nicely - I had never come across the @* before, thanks! – the_velour_fog Nov 13 '15 at 11:12
  • I'm glad it helped you. I've edited the answer to propose another solution. – saginaw Nov 13 '15 at 11:20
  • 1
    nice one, I tried your suggestion about using : <C-r>a it actually worked fine too :) I guess vim read the ^M's as line returns - and executed each one as its own individual line / command? – the_velour_fog Nov 13 '15 at 11:54
  • That's a good question, honestly I don't know. Usually if I don't delete this character I've got errors. I'm glad it worked for you without errors. Maybe someone with more knowledge on the subject will explain to us how vim treats that kind of special characters. – saginaw Nov 13 '15 at 12:06

I actually do it a bit differently, I just make the edits in my vimrc and re-source it every time I write it. (I have a cascading set of vimrc files so this allows me to change any one of them.)

if $MYVIMRC != ''
    autocmd BufWritePost    *vimrc      source $MYVIMRC

More directly to the question than my other answer, you could define a mapping to like this (nnoremap for no selection, just execute the current line; vnoremap for when visual mode is active):

nnoremap <F2> :execute getline(".")<CR>
vnoremap <F2> :<C-u>for line in getline("'<", "'>") \| execute line \| endfor<CR>

In both cases, the "current line" is :executed, so in the visual version you're :executeing one line after another through the visual selection.

As stated in another answer, the <C-u> deletes the range specification that pops up in the command line when : is typed. The | characters need to be escaped because otherwise they're interpreted as the end of the vnoremap command.

This could also be turned into a function to get rid of some of the escape gymnastics but it doesn't seem like a huge win to me at this time. It would basically be the vnoremap expanded into multiple lines and called with a range or not depending on the [nv] mapping mode.

  • Oh, the visual mode mapping executes entire lines so if you're block- or character-wise it'll ignore the start and end points within the lines. – dash-tom-bang Jun 6 '16 at 18:09

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.