Pan Ruochen
Pan Ruochen

Reputation: 2070

vim substitutes with cursor keeping its position

I wish vim to remove all trailing spaces automatically keeping the cursor in its current position, so I use the following autocmd in my vimrc

autocmd BufWritePre *
\ exec "%s/\\s\\+$//e" | exec 'normal ``'

It works well normally. But if nothing is changed since last writing, a 'w' command will lead the cursor move to the last position when last writing is executed. What should I do if I wish the cursor keep its position unconditionally.

Upvotes: 0

Views: 92

Answers (3)

Ben
Ben

Reputation: 8905

You can avoid writing the file if the file has not changed, by either using the :update command to do the write, or by checking the for the "modified" option in your autocmd, like autocmd BufWritePre * if &modified | ... | endif.

Upvotes: 0

Ingo Karkat
Ingo Karkat

Reputation: 172510

You can manually set the mark first via :normal! m', but it's better to save the entire view, as jumping back to the mark just restores the cursor position, but not necessarily the entire view inside the window (in case scrolling occurred).

autocmd BufWritePre *
\ let g:saveview = winsaveview() |
\ %s/\s\+$/e" |
\ call winrestview(g:saveview)

This still suffers from clobbering your search pattern (which wrapping in a :function could fix).

I would recommend to use a tested and more configurable plugin instead. Coincidentally, I've developed the DeleteTrailingWhitespace plugin that can do automatic, unconditional deletion via the following configuration:

let g:DeleteTrailingWhitespace = 1
let g:DeleteTrailingWhitespace_Action = 'delete'

Upvotes: 1

Codie CodeMonkey
Codie CodeMonkey

Reputation: 7946

You can use the command silent! to avoid the error caused by the failed match from affecting the rest of your command:

exec "silent! %s/\\s\\+$//e" | exec 'normal ``'

See :help silent.

Upvotes: 1

Related Questions