关于自动化:如何在vim中自动删除尾随空格

How can you automatically remove trailing whitespace in vim

我试图在git中提交一些文件时出现"尾随空白"错误。

我想在保存python文件之前自动删除这些尾随的空白字符。

你能配置vim来做到这一点吗? 如果是这样,怎么样?


我在这里找到了答案。

将以下内容添加到我的.vimrc文件中就可以了。

1
autocmd BufWritePre *.py :%s/\s\+$//e


编译以上加上保存光标位置:

1
2
3
4
5
6
7
8
fun! <SID>StripTrailingWhitespaces()
    let l = line(".")
    let c = col(".")
    %s/\s\+$//e
    call cursor(l, c)
endfun

autocmd FileType c,cpp,java,php,ruby,python autocmd BufWritePre <buffer> :call <SID>StripTrailingWhitespaces()

如果要在保存到任何文件时应用此功能,请省略第二个autocmd并使用通配符*

1
autocmd BufWritePre * :call <SID>StripTrailingWhitespaces()


我通常也有一个:

1
match Todo /\s\+$/

在我的.vimrc文件中,以便行尾空白为高亮显示。

Todo是一个语法高亮组名,用于高亮显示关键字,如TODOFIXMEXXX。它有一种令人讨厌的淡黄色背景颜色,我发现它是你在代码中不想要的东西最好的东西:-)


我都突出显示现有的尾随空格,并剥离尾随空格。

我将我的编辑器(vim)配置为在末尾显示空白区域,例如

enter image description here

在我的.vimrc的底部:

1
2
3
4
5
6
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()

并且我在保存它们时从文件中自动删除它,在我的情况下* .rb用于ruby文件,再次在我的?/ .vimrc中

1
2
3
4
function! TrimWhiteSpace()
    %s/\s\+$//e
endfunction
autocmd BufWritePre     *.rb :call TrimWhiteSpace()


这是一种通过多个FileType进行过滤的方法。

1
autocmd FileType c,cpp,python,ruby,java autocmd BufWritePre <buffer> :%s/\s\+$//e


复制并粘贴自http://blog.kamil.dworakowski.name/2009/09/unobtrusive-highlighting-of-trailing.html(该链接不再有效,但您需要的位于下方)

"这样做的好处是不会突出显示您在行尾输入的每个空格,只有当您打开文件或退出插入模式时才会这样。非常整洁。"

1
2
3
4
5
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\+$/


我在评论中看到了这个解决方案
VIM Wikia - 删除不需要的空格

我真的很喜欢它。在不需要的空格上添加.

enter image description here

把它放在你的.vimrc

1
2
3
4
5
6
7
8
9
10
11
" 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()

这就是我的做法。我不记得从哪里偷了它。

1
2
3
4
5
autocmd BufWritePre * :call <SID>StripWhite()
fun! <SID>StripWhite()
    %s/[ \t]\+$//ge
    %s!^\( \+\)\t!\=StrRepeat("\t", 1 + strlen(submatch(1)) / 8)!ge
endfun


在所有情况下都不能接受简单地从文件中删除尾随空格的解决方案。它将在一个从一开始就有这个策略的项目中工作,所以没有这样的空白,你不只是在你即将到来的提交中添加自己。

假设您只希望不添加尾部空格的新实例,而不影响您未编辑的行中的现有空格,以使您的提交不受与您的工作无关的更改。

在这种情况下,使用git,您可以使用如下脚本:

1
2
3
4
5
6
7
#!/bin/sh

set -e # bail on errors

git stash save commit-cleanup
git stash show -p | sed '/^\+/s/ *$//' | git apply
git stash drop

也就是说,我们存储更改,然后过滤diff中的所有+行,以便在我们将更改重新应用到工作目录时删除它们的尾随空格。如果此命令管道成功,我们将删除存储。


.vimrc文件中使用时,其他方法在MacVim中以某种方式对我不起作用。所以这里有一个可以突出显示尾随空格的内容:

1
2
3
set encoding=utf-8
set listchars=trail:·
set list


如果你修剪空格,你应该只对已经干净的文件进行修剪。"在罗马的时候..."。在处理虚假变化不受欢迎的代码库时,这是一个很好的礼仪。

此功能检测尾随空白,并且只有在已经清洁时才开启修剪。

这个想法的功劳在这里发表评论的宝石:https://github.com/atom/whitespace/issues/10(有史以来最长的错误票评论流)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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


对于想要针对特定??文件类型运行它的人(FileTypes并不总是可靠的):

1
autocmd BufWritePre *.c,*.cpp,*.cc,*.h,*.hpp,*.py,*.m,*.mm :%s/\s\+$//e

或者使用vim7:

1
autocmd BufWritePre *.{c,cpp,cc,h,hpp,py,m,mm} :%s/\s\+$//e

autocmd BufWritePre * :%s/\s\+$//:let @/=''