Prevent Vim from jumping to the beginning when invoking % range function

Viewed 34

I'm defining a Vim function:

function! HelloWorld() range
  echo "hello world"
endfunction

I open a text file with many lines with vim -u NONE filename.txt, jump to the last line with G, and call HelloWorld() with :%call HelloWorld(). I notice the cursor jumps to the first line. How to prevent this, i.e. keeping the cursor at current line? Thanks a lot!

P.S. The function mentioned above is just a minimal example. I know the problem disappears if I remove the range and call with :call HelloWorld(), but it's needed in my actual problem.


Edit:

function! HelloWorld() range
  let l:win_view = winsaveview()
  echo "hello world"
  call winrestview(l:win_view)
endfunction

won't work.

2 Answers

Thanks @Matt. I eventually come up with the following solution. Keep function HelloWorld intact, then define a command that wraps around the function call. The idea is stolen from vim-autoformat.

command! -range -bar HelloWorld 
            \ let winview=winsaveview() |
            \ <line1>,<line2>call HelloWorld() |
            \ call winrestview(winview)

Now invoking :%HelloWorld will echo the text and won't move the cursor.

My only concern about this solution is the global scope of the variable winview. I haven't seen any unpleasant side-effect till now though.

Maybe try this way:

function! HelloWorld() range

  " get current cursor position
  let l = line('.')
  let c = col('.')

  echo "hello world"

  " restore original cursor position
  call cursor(l,c)

endfunction
Related