Don't replace selected text when executing an autocmd in VIM

Tag: vim , vimrc , macvim Author: iamaster Date: 2012-02-24

I have the following autocmd in my .vimrc:

autocmd FocusLost,BufLeave,BufWritePre *.py :exe "normal! ma" | :%s/\s\+$//e | :exe "normal `a"

This command has the purposes to remove all trailing whitespace from my buffer while keeping the cursor at the current position.

The problem is that when the command is invoked and some text is selected, the text is replaced by ma. How can I modify my autocmd declaration in order to:

  • Still work when some text is selected
  • Keep the text intact
  • Keep the selection if some text was selected
  • Keep the cursor position if no text was selected

Note: I'm using MacVim.

Best Answer

You can save the cursor position (and overall window “view”) with winsaveview(). The saved position (and view) can be restored with winrestview().

The following code uses the buffer-local variable b:spacestrip_view to store the view (instead of overwriting the mark a):

autocmd FocusLost,BufLeave,BufWrite *.py let b:spacestrip_view=winsaveview()|%s/\s\+$//e|call winrestview(b:spacestrip_view)

comments:

Works flawlessly... didn't know about win(save|rest)view(). Thanks!