在Git中提交一些文件时,我得到了“尾随空白”错误。

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

您可以配置Vim来实现这一点吗?如果有,怎么做?


当前回答

我就是这么做的。我不记得从哪里偷来的了。

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

其他回答

简单地从文件中去除尾随空格的解决方案在所有情况下都是不可接受的。它将在从一开始就具有此策略的项目中工作,因此在即将提交的提交中没有这样的空白。

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

在这种情况下,使用git,你可以使用这样的脚本:

#!/bin/sh

set -e # bail on errors

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

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

如果要删除空白,应该只对已经是干净的文件进行处理。“在罗马的时候……”在不欢迎虚假更改的代码库上工作时,这是一种良好的礼仪。

此函数检测尾随空格,并仅在已经清除的情况下开启修剪。

这个想法的功劳来自这里的一个评论:https://github.com/atom/whitespace/issues/10(有史以来最长的bug票评论流)

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

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

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()

如果你想在保存到任何文件时应用此命令,请省略第二个autocmd并使用通配符*:

autocmd BufWritePre,FileWritePre,FileAppendPre,FilterWritePre *
  \ :call <SID>StripTrailingWhitespaces()

autocmd BufWritePre *: % s / \ \ + $ / / < CR >:让@ / = " < CR >

我就是这么做的。我不记得从哪里偷来的了。

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