I am getting 'trailing whitespace' errors trying to commit some files in Git.
I want to remove these trailing whitespace characters automatically right before I save Python files.
Can you configure Vim to do this? If so, how?
I am getting 'trailing whitespace' errors trying to commit some files in Git.
I want to remove these trailing whitespace characters automatically right before I save Python files.
Can you configure Vim to do this? If so, how?
I found the answer here.
Adding the following to my .vimrc file did the trick:
autocmd BufWritePre *.py :%s/\s\+$//e
The e
flag at the end means that the command doesn't issue an error message if the search pattern fails. See :h :s_flags
for more.
gi
will put you back on the previous cursor position. –
Scoville :%!sed -r 's/\s+$//'
as the command seems to be another way (besides keepjumps
) to prevent moving the cursor. See :h filter
. –
Tuantuareg gi
jumps to the last position where text was inserted (not always the cursor position before the :%s
command) and :%!sed -r 's/\s+$//'
jumps to the beginning of the file. I don't get how keepjumps
is supposed to be used, :keepjumps :%s/\s+$//e
doesn't seem to do anything different. I'm using :%s/\s\+$//e|normal ''
and it seems to work as I expect (goes to the cursor position before using the :%s
command). –
Foliose :%s/\s\+$//e|normal ''
will jump to the wrong position if no trailing whitespaces were found. –
Foliose e
at the end means, if we did not find the pattern, vi does not consider the substitute command as failed –
Zonda Compilation of above plus saving cursor position:
function! <SID>StripTrailingWhitespaces()
if !&binary && &filetype != 'diff'
let l:save = winsaveview()
keeppatterns %s/\s\+$//e
call winrestview(l:save)
endif
endfun
autocmd FileType c,cpp,java,php,ruby,python autocmd BufWritePre <buffer> :call <SID>StripTrailingWhitespaces()
If you want to apply this on save to any file, leave out the second autocmd
and use a wildcard *
:
autocmd BufWritePre,FileWritePre,FileAppendPre,FilterWritePre *
\ :call <SID>StripTrailingWhitespaces()
autocmd FileType c,cpp,java,php,ruby,python
part to make it apply to all files. –
Barrettbarrette <buffer>
with *
if you want it to work on all files –
Bolshevist keepp
, it will not alter your search history, i.e. keepp %s/\s\+$//e
–
Cortex undojoin
to stop this from polluting your undo history: autocmd BufWritePre * undojoin | :call <SID>StripTrailingWhitespaces()
–
Golda \m
to the pattern to be independent of the magic option. Save position better with let l:save = winsaveview()
and call winrestview(l:save)
. Add if !&binary && &filetype != 'diff'
to ignore on binary and diff files (E.g. patch file to remove white spaces). –
Pow I also usually have a :
match Todo /\s\+$/
in my .vimrc
file, so that end of line whitespace are hilighted.
Todo being a syntax hilighting group-name that is used for hilighting keywords like TODO
, FIXME
or XXX
. It has an annoyingly ugly yellowish background color, and I find it's the best to hilight things you don't want in your code :-)
:hi Todo
. So I perused :hi <Tab>
and :help hi
. I considered Cursor
and Error
, but I think I'll try match VisualNOS /\s\+$/
. I might combine this with some of the autocmd
s from other answers here. –
Hatch I both highlight existing trailing whitespace and also strip trailing whitespace.
I configure my editor (vim) to show white space at the end, e.g.
with this at the bottom of my .vimrc:
highlight ExtraWhitespace ctermbg=red guibg=red
match ExtraWhitespace /\s\+$/
autocmd BufWinEnter * match ExtraWhitespace /\s\+$/
autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/
autocmd InsertLeave * match ExtraWhitespace /\s\+$/
autocmd BufWinLeave * call clearmatches()
and I 'auto-strip' it from files when saving them, in my case *.rb for ruby files, again in my ~/.vimrc
function! TrimWhiteSpace()
%s/\s\+$//e
endfunction
autocmd BufWritePre *.rb :call TrimWhiteSpace()
Here's a way to filter by more than one FileType.
autocmd FileType c,cpp,python,ruby,java autocmd BufWritePre <buffer> :%s/\s\+$//e
I saw this solution in a comment at VIM Wikia - Remove unwanted spaces
I really liked it. Adds a .
on the unwanted white spaces.
.vimrc
" Removes trailing spaces
function TrimWhiteSpace()
%s/\s*$//
''
endfunction
set list listchars=trail:.,extends:>
autocmd FileWritePre * call TrimWhiteSpace()
autocmd FileAppendPre * call TrimWhiteSpace()
autocmd FilterWritePre * call TrimWhiteSpace()
autocmd BufWritePre * call TrimWhiteSpace()
Copied and pasted from http://blog.kamil.dworakowski.name/2009/09/unobtrusive-highlighting-of-trailing.html (the link no longer works, but the bit you need is below)
"This has the advantage of not highlighting each space you type at the end of the line, only when you open a file or leave insert mode. Very neat."
highlight ExtraWhitespace ctermbg=red guibg=red
au ColorScheme * highlight ExtraWhitespace guibg=red
au BufEnter * match ExtraWhitespace /\s\+$/
au InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/
au InsertLeave * match ExtraWhiteSpace /\s\+$/
This is how I'm doing it. I can't remember where I stole it from tbh.
autocmd BufWritePre * :call <SID>StripWhite()
fun! <SID>StripWhite()
%s/[ \t]\+$//ge
%s!^\( \+\)\t!\=StrRepeat("\t", 1 + strlen(submatch(1)) / 8)!ge
endfun
%s
the global (g) flag is as useless as a space at EOL :-) –
Aliform A solution which simply strips trailing whitespace from the file is not acceptable in all circumstances. It will work in a project which has had this policy from the start, and so there are no such whitespace that you did not just add yourself in your upcoming commit.
Suppose you wish merely not to add new instances of trailing whitespace, without affecting existing whitespace in lines that you didn't edit, in order to keep your commit free of changes which are irrelevant to your work.
In that case, with git, you can can use a script like this:
#!/bin/sh
set -e # bail on errors
git stash save commit-cleanup
git stash show -p | sed '/^\+/s/ *$//' | git apply
git stash drop
That is to say, we stash the changes, and then filter all the +
lines in the diff to remove their trailing whitespace as we re-apply the change to the working directory. If this command pipe is successful, we drop the stash.
For people who want to run it for specific file types (FileTypes are not always reliable):
autocmd BufWritePre *.c,*.cpp,*.cc,*.h,*.hpp,*.py,*.m,*.mm :%s/\s\+$//e
Or with vim7:
autocmd BufWritePre *.{c,cpp,cc,h,hpp,py,m,mm} :%s/\s\+$//e
The other approaches here somehow didn't work for me in MacVim when used in the .vimrc
file. So here's one that does and highlights trailing spaces:
set encoding=utf-8
set listchars=trail:·
set list
set listchars=trail:·
saying: E474: Invalid argument: listchars=trail:·
. Can you validate your example? –
Bothy If you trim whitespace, you should only do it on files that are already clean. "When in Rome...". This is good etiquette when working on codebases where spurious changes are unwelcome.
This function detects trailing whitespace and turns on trimming only if it was already clean.
The credit for this idea goes to a gem of a comment here: https://github.com/atom/whitespace/issues/10 (longest bug ticket comment stream ever)
autocmd BufNewFile,BufRead *.test call KarlDetectWhitespace()
fun! KarlDetectWhitespace()
python << endpython
import vim
nr_unclean = 0
for line in vim.current.buffer:
if line.rstrip() != line:
nr_unclean += 1
print "Unclean Lines: %d" % nr_unclean
print "Name: %s" % vim.current.buffer.name
cmd = "autocmd BufWritePre <buffer> call KarlStripTrailingWhitespace()"
if nr_unclean == 0:
print "Enabling Whitespace Trimming on Save"
vim.command(cmd)
else:
print "Whitespace Trimming Disabled"
endpython
endfun
fun! KarlStripTrailingWhitespace()
let l = line(".")
let c = col(".")
%s/\s\+$//e
call cursor(l, c)
endfun
let _s=@/
and restore it at the end ` let @/=_s` .In this case we are using black hole register –
Compliant autocmd BufWritePre *.py execute 'norm m`' | %s/\s\+$//e | norm g``
This will keep the cursor in the same position as it was just before saving
© 2022 - 2024 — McMap. All rights reserved.