I like using Vim's virtualedit=all feature, but I also like being able to click after the end of a line and have the cursor go directly to the end of the line (instead of going to the exact position I clicked on). Is there a plugin or something that can make Vim's cursor-placement following a mouse click act more intelligently? Ideally, I'd like it to do either of the following:

  • Ignore virtualedit preference on mouse-click: On a mouse-click, if the click occurred after the last character on the line, Vim would position the cursor at the end of the line regardless of whether virtualedit is turned on.
  • Mode-dependent mouse-click behavior: In normal mode, mouse-click after end-of-line causes cursor to jump to the last character; in insert mode, cursor is positioned under mouse.
  • MS-Word style behavior (preferabale): Cursor jumps to end of line on single click, or to virtualedit position on double-click

I know that I could just switch from virtualedit-all to virtualedit-block, but I prefer virtualedit=all for everything except mouse-click behavior. (Actually, I even like being able to position the cursor in the middle of a tab character using a mouse-click, so it's really just the behavior of clicking after the last character in a line.)

P.S. Please, no comments or answers suggesting I just teach myself not to use the mouse. Mouse-usage is one of the reasons I switched from Vim to gVim, because frankly it's extremely convenient sometimes, even if your primary method of movement in a file is keyboard-only.

EDIT: Added mode-dependent idea.


Mouse-clicks are mappable just like key presses in Vim. So you can remap a mouse click to set virtualedit as you like, then do the mouseclick, then set it back.

Insert mode is more complicated than I care to try at the moment, but normal mode is easy. Something like this should work, although it would be even better to save and restore virtualedit rather than setting it explicitly:

nnoremap <silent> <LeftMouse> :set virtualedit=<CR><LeftMouse>:set virtualedit=all<CR>

It is also possible to remap a double-click in similar fashion, using <2-LeftMouse> instead of <LeftMouse>. Some experimentation showed it may not be needed. But since double-clicking by default puts you in visual select mode, you might want a mapping like:

nnoremap <silent> <2-LeftMouse> <LeftMouse>

I couldn't actually get that working, however. I couldn't figure out how to get it to stay out of visual mode, even with that mapping and several similar applied.

EDIT (by OP; I want to post my "final" solution here so others can see it, but I don't want to post a separate answer, since this answer is really the one I needed):

Here's what I ended up putting in my .vimrc:

function! TempNonVirtual()
    let g:oldvirtualedit=&virtualedit
    set virtualedit=
function! RestoreVirtual()
    let &virtualedit=g:oldvirtualedit
set virtualedit=all
nnoremap <silent> <LeftMouse> :call TempNonVirtual()<CR><LeftMouse>:call RestoreVirtual()<CR> 

I'd like to combine those two functions into a single function called NonVirtualClick or something that would save the old virtualedit setting, do the click, and then restore the setting, but <LeftMouse> isn't a command so it doesn't work inside of a function. (Hints about how to get around this would be welcome...)

  • I also added the following mapping, which does seem to work for me: nnoremap <silent> <2-LeftMouse> <LeftMouse>i. For some reason "double-click to enter insert mode" just seems logical to me. Ideally I'd like to only do this if the cursor is past the end of the line and keep the standard behavior otherwise, which should be fairly easy using col('$') and getpos, but for now I'll leave it as-is. Thanks again! – Kyle Strand Feb 10 '14 at 21:18
  • Actually, that mapping seems kind of...inconsistent. Sometimes it puts me in VISUAL INSERT mode, sometimes it puts me in VISUAL mode and highlights a large chunk of the line... – Kyle Strand Feb 10 '14 at 22:11

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.