Here is an attempt to write a function which will remove trashy characters (^F, ^S, ^Z, zero-width space, etc) on save, and keep cursor position.
colorscheme desert
set guifont=Consolas:h10
set encoding=utf-8
setglobal fileencoding=utf-8
set noexpandtab
set list
set listchars=tab:→\ ,space:·
set nobackup
set noswapfile
set noundofile
function! RemoveTrash()
let l:save = winsaveview()
keeppatterns %s/[^[:print:]\t]//g
call winrestview(l:save)
endfun
augroup Test
autocmd!
autocmd BufWritePre * :call RemoveTrash()
augroup END
The overall idea about function was taken from Martin Tournoij's answer about removing whitespace: https://vi.stackexchange.com/a/456, and regex was taken lincz's answer: https://stackoverflow.com/a/16135425.
Here is the test file:
>---foo##bar##baz
>---foo##bar##baz
>---foo##bar##baz
To post it here I replaced tab characters with >---
and control characters (^F
, ^S
) with ##
.
However, when I save the file, the cursor position isn't really saved - it slightly moves to the right side accordingly number of control characters before it. Here are two examples:
- If you have cursor on letter
a
inbar
- it will be moved tor
. - If you have cursor on letter
b
inbaz
- it will be moved toz
(because there are two control characters before it).
And here are screenshots for the first example:
How to fix it?
DJMcMayhem posted an answer at February the 5th, but it seems it doesn't properly work for tab-indented lines. That's why I started a bounty. I tried to fix it by changing getcurpos()[2]
to getcurpos()[4]
, but my "knowledge" of Vimscript is too low.