如何自动删除vim中的尾随空格

Posted

技术标签:

【中文标题】如何自动删除vim中的尾随空格【英文标题】:How can you automatically remove trailing whitespace in vim 【发布时间】:2010-09-26 05:57:30 【问题描述】:

我在尝试在 Git 中提交某些文件时遇到“尾随空格”错误。

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

你能配置 Vim 来做到这一点吗?如果有,怎么做?

【问题讨论】:

这与python无关 使用我的DeleteTrailingWhitespace插件。 相关:What's the simplest way to strip trailing whitespace from all lines in a file? 在 Vim SE 【参考方案1】:

我找到了答案here。

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

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

末尾的e 标志意味着如果搜索模式失败,该命令不会发出错误消息。请参阅:h :s_flags 了解更多信息。

【讨论】:

有趣!尾随空白是一场战斗。我讨厌它,其他人不明白为什么。我们使用与 vim 一样多的 vi(我使用 vim;他们没有,因为他们必须安装它)。我有一个程序,我调用 stb 来去除尾随空白,并将其用作过滤器;也可以在 vi 中使用。这样更好。 这会在每次保存时更改光标位置。有可能避免吗? 既然这是这个问题的实际答案,也许应该更新它以保持光标位置。 这也将删除多行字符串中的尾随空格,这在某些情况下可能不需要。但我想没有简单的方法可以避免这种情况? 也许你可以明确指出最后的e 意味着,如果我们没有找到模式,vi 不会认为替换命令失败【参考方案2】:

我通常也有一个:

match Todo /\s\+$/

在我的.vimrc 文件中,以突出显示行尾空格。

Todo 是一种语法高亮 group-name,用于高亮关键字,如 TODOFIXMEXXX。它有一种令人讨厌的难看的淡黄色背景色,我发现最好在代码中突出显示您想要的东西 :-)

【讨论】:

或者你可以设置list,设置listchars+=trail:. 优秀 - 这是自动删除尾随空格之间的完美中间地带(即使我可能没有意识到它,或者当它是我恰好在同一个文件中工作的其他人的代码时) ),不做任何事情。谢谢。 不幸的是,我最喜欢的配色方案 zenburn 没有突出显示 @PeterLong,也不适用于 railscasts 主题。使用:hi Todo 进行检查。所以我仔细阅读了:hi <Tab>:help hi。我考虑过CursorError,但我想我会尝试match VisualNOS /\s\+$/ 。我可能会将其与此处其他答案中的一些autocmds 结合起来。【参考方案3】:

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

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

【讨论】:

嗯,如果你最终打开二进制文件,在“*”上这样做是很危险的,它们最终可能会变得非常糟糕。 是的,可能不是最聪明的,但我也不将 vim 用于十六进制编辑器。除非您保存,否则不会执行。 我认为这比列出您可能处理的每个文件类型的替代方案要好,不是吗?我工作在 rb、php、cs、html、sass、css、js、coffee、xml、xslt、pl 等等等等……有没有快乐的媒介? 除非您在 vim 中写入二进制文件,否则这可能永远不会成为问题。 它出现在第一个%s 中,全局 (g) 标志与 EOL 处的空格一样无用 :-)【参考方案4】:

上面的编译加上保存光标位置:

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

【讨论】:

您可以通过保存最后一次搜索并恢复它来改善您的功能。让_s=@/让@/=_s 我删除了autocmd FileType c,cpp,java,php,ruby,python 部分以使其适用于所有文件。 @xApple:在函数内部,不需要保存和恢复上次搜索 - 离开函数上下文会解决这个问题。 @swt83 如果您希望它适用于所有文件,您还需要将&lt;buffer&gt; 替换为* 如果你在替换命令前加上keepp,它不会改变你的搜索历史,即keepp %s/\s\+$//e【参考方案5】:

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

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

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 link“使用匹配命令”下找到相同的解决方案。【参考方案6】:

这是一种按多个文件类型进行过滤的方法。

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

【讨论】:

每个文件:autocmd FileType * autocmd BufWritePre :%s/\s\+$//e【参考方案7】:

我既突出了现有的尾随空格,又去掉了尾随空格。

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

在我的 .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()

我在保存文件时从文件中“自动剥离”它,在我的情况下 *.rb 用于 ruby​​ 文件,再次在我的 ~/.vimrc 中

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

【讨论】:

太棒了!谢谢!,我特别喜欢这个功能。【参考方案8】:

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

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

在这种情况下,通过 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 中的所有+ 行以删除它们的尾随空格,因为我们将更改重新应用到工作目录。如果此命令管道成功,我们将删除存储。

【讨论】:

【参考方案9】:

当在.vimrc 文件中使用时,这里的其他方法在 MacVim 中对我不起作用。所以这是一个突出尾随空格的方法:

set encoding=utf-8
set listchars=trail:·
set list

【讨论】:

执行set listchars=trail:· 说:E474: Invalid argument: listchars=trail:·。你能验证你的例子吗? @kenorb 见***.com/questions/18321538/…【参考方案10】:

autocmd BufWritePre * :%s/\s\+$//&lt;CR&gt;:let @/=''&lt;CR&gt;

【讨论】:

【参考方案11】:

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

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

或者用 vim7:

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

【讨论】:

【参考方案12】:

如果您修剪空白,您应该对已经干净的文件执行此操作。 “在罗马的时候...”。在处理不受欢迎的虚假更改的代码库时,这是一种很好的礼仪。

此函数检测尾随空格并仅在它已经干净时才打开修剪。

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

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=@/并在最后恢复它`let @/=_s`。在这种情况下我们使用黑洞寄存器【参考方案13】:

我在评论中看到了这个解决方案 VIM Wikia - Remove unwanted 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()

【讨论】:

【参考方案14】:
autocmd BufWritePre *.py execute 'norm m`' | %s/\s\+$//e | norm g``

这将使光标保持在保存前的相同位置

【讨论】:

以上是关于如何自动删除vim中的尾随空格的主要内容,如果未能解决你的问题,请参考以下文章

如何使用正则表达式删除尾随空格?

如何在 Visual Studio 2008 中自动删除尾随空格?

如何在 Matlab 中保存时自动删除尾随空格?

让 Git 在提交前自动删除尾随空格

如何使用正则表达式删除尾随空格?

如何删除前导和尾随的空格以及字符串中的多个空格? [复制]