Normally, when I use the up/down arrow keys to move between lines in insert mode (I'm using Vim wrong, I know), Vim remembers which column my cursor is in, so if I move to a line shorter than where my cursor is, then back to a longer line, the cursor pops right back to the same column. This is what I want and expect to happen, as well as what happens most of the time.

However, when I'm editing a Java sourcecode file and the last character in the shorter line is an opening or closing curly brace, square bracket, or parenthesis, Vim seems to forget entirely that the cursor was ever in any column other than the one immediately after the brace. The result is the I often find my cursor near the beginning of a line of code when I want and expect it to be at the end, so I have to $a to get back. Since this is Java, I have a lot of short lines ending with curly braces- so this is really annoying.

The weird part is that this only happens in insert mode- in normal mode, the arrows as well as j and k work fine. It's also weird that it only happens with those six grouping symbols- blank lines, lines with only whitespace, typical comments, and lines ending with semicolons cause no trouble in either mode.

It's not a bug in the Java plugin that I'm using- the exact same behavior happens in a .txt file.

I tried typing :au CursorHold, as instructed by one or two other answers to related questions, but it only prints --- Auto-Commands --- in purple text, and nothing to direct me to a bugged script.

Related: I recently upgraded my Apple-installed version of Vim 7.3 to Homebrew-installed Vim 7.4, which did not have this problem. I'm also on a Mac (and no, I'm not using GVim or MacVim).

Edit: I derped in writing the last paragraph above. Apple's Vim 7.3 install did not have this issue; Homebrew's Vim 7.4 did. Not that it matters now...

  • I am unable to reproduce this problem using the Vim 7.3 that comes with OS X 10.9. – 200_success Apr 21 '15 at 8:00
  • 1
    How about :au CursorHoldI or :au CursorMovedI ( both ending with uppercase i )? – tivn Apr 21 '15 at 9:21
  • Please show exact Vim version – Christian Brabandt Apr 21 '15 at 19:13
  • I can't reproduce on vim 7.4.448 – Cody Poll Apr 21 '15 at 20:20
  • 1
    I can not reproduce with Vim 7.4 patches 1-622 using vim -u NONE. I would recommend you disable your plugins and vimrc customization until you find the culprit. protip: use a binary search to make it quicker. – Peter Rincker Apr 21 '15 at 21:01

Problem solved! I tried typing :au CursorMovedI as tivn suggested in the comments, which said something about matchparen. I then typed :scriptnames, and lo and behold, it showed a matchparen.vim plugin installed in one of Homebrew's directories. CursorMovedI appeared in that file exactly once, in an augroup that looked like this:

augroup matchparen
  " Replace all matchparen autocommands
  autocmd! CursorMoved,CursorMovedI,WinEnter * call s:Highlight_Matching_Pair()
  if exists('##TextChanged')
    autocmd! TextChanged,TextChangedI * call s:Highlight_Matching_Pair()
augroup END

I then commented out the third line (the first autocmd! line) by prepending it with a quote, restarted Vim, and everything seems to be working fine.

If anything else breaks because of this, I'll know where to look.

Thanks to @tivn for pointing out :au CursorMovedI (that's a capital i at the end), which led me to this solution.

This fix appears to break the matching parenthesis highlighting; however, thanks to @tivn again, the source of the problem appears to be a bug in either the getcurpos() or setpos() functions called later in my matchparen.vim.

Both of these commands exist in if statements that appear to use these functions if the exist, or use the winsaveview() or winrestview(). Commenting out these if statements so that the win...view() functions are called no matter what fixes the cursor issue without also breaking the parenthesis highlighting.

As an example, here's the code on lines 88-99 of the unedited plugin file installed by Homebrew:

    let has_getcurpos = exists("*getcurpos")
    if has_getcurpos
      " getcurpos() is more efficient but doesn't exist before 7.4.313.
      let save_cursor = getcurpos()
      let save_cursor = winsaveview()

Commenting out the inner if statement, except the line containing winsaveview(), results in this:

    let has_getcurpos = exists("*getcurpos")
 "   if has_getcurpos
 "     " getcurpos() is more efficient but doesn't exist before 7.4.313.
 "     let save_cursor = getcurpos()
 "   else
      let save_cursor = winsaveview()
 "   endif

Making this change, doing the same to lines 163-169, and uncommenting the autocmd! line above, seems to solve the cursor issue without causing any more.

Also, I'm using Vim 7.4.488. A pastebin of my matchparen.vim with these edits is available here.

  • You should send Bram a bug report via the vim_use or vim_dev mailing list. – romainl Apr 22 '15 at 7:47
  • 1
    Good to know that. By comparing matchparen.vim between Vim 7.3 and 7.4, I am able to narrowing this to save_cursor variable used in the file. Rather than disabling autocmd, you can instead replace let save_cursor = getcurpos() and call setpos('.', save_cursor) with let save_cursor = winsaveview() and call winrestview(save_cursor) respectively. This way you don't loose the parenthesis pair highlighting. – tivn Apr 22 '15 at 12:28
  • I can't imagine why getcurpos() wouldn't work. In any case, a reproducable example of the problem should be posted to the vim-dev mailinglist, so Bram can fix the plugin. – Christian Brabandt Apr 22 '15 at 18:05
  • Probably related to this: groups.google.com/forum/#!topic/vim_dev/CMAGD6obzKo – tivn Apr 23 '15 at 6:57
  • 1
    That is a fixed by 7.4.578 (probably that's why I can't reproduce it), So please try with a newer Vim. – Christian Brabandt Apr 23 '15 at 9:36

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.