e-pirate
e-pirate

Reputation: 193

Prevent vim from jumping through source code

folks!

I'm using vim as an IDE for writing code in bash, Python and C. Besides, I have a key map to execute my current buffer depending on the file type. Here is a responsible parts of my .vimrc:

...
autocmd FileType python call Python_source()
autocmd FileType sh call Bash_source()
...
" Read lw (lispwords) modelise from current buffer and pass it as command arguments
func! LWargs()
    set lw=''
    doautocmd BufRead
    if len(&lw) > 0 && len(&lw) < 512
        return ' ' . &lw
    endif
    return ''
endfunc

func! Python_source()
    setlocal number cursorline
    setlocal shiftwidth=2
    setlocal foldmethod=indent

    map <F9> :w \| :exe '!python' '%:p' . LWargs()<CR>
    imap <F9> <Esc> :w \| :exe '!python' '%:p' . LWargs()<CR>

    " Comments on Ctrl-C
    map <C-C> :call ToggleComment('#')<CR>
    imap <C-C> <Esc>:call ToggleComment('#')<CR>li
endfunc

func! Bash_source()
    setlocal number cursorline
    setlocal shiftwidth=4

    map <F9> :w \| :!./%<CR>
    imap <F9> <Esc> :w \| :!./%<CR>

    map <C-C> :call ToggleComment('#')<CR>
    imap <C-C> <Esc>:call ToggleComment('#')<CR>li
endfunc
...

So, when I press F9, the magic happen and my code is executed with arguments passed by the LWargs. The only problem is after the program exits, vim will jump to the beginning of the file forcing me to position cursor back the line I was working and making my life harder. Is there is any way to prevent vim from jumping around?

Upvotes: 2

Views: 162

Answers (1)

filbranden
filbranden

Reputation: 8898

The issue is with the doautocmd BufRead command in your LWargs(), which resets the cursor position to the top of the file.

(At least in my case, the command used to restore cursor position upon opening Vim is the one causing the cursor to move. You can inspect the list from :autocmd BufEnter * to see if you can spot a similar command or another one that might be causing the cursor to move. Looking again, it turns out I was also getting that same rule from my Linux distribution...)

A good way to prevent this is to use winsaveview() to save the cursor location and the window view in general (which line is at the top, whether your window is scrolled right to a column when word wrap is off) and winrestview() to restore it.

Here's an updated LWargs() that won't move your cursor:

function! LWargs()
    set lw=
    let saved_view = winsaveview()
    doautocmd BufRead
    call winrestview(saved_view)
    if len(&lw) > 0 && len(&lw) < 512
        return ' ' . &lw
    endif
    return ''
endfunction

Note also that the correct syntax is set lw=, if you use set lw='' you'll be setting a two-character string with two single quotes.

Upvotes: 3

Related Questions