如何修剪Vim文件末尾的空白行?

gen*_*nad 28 vim

有时我会在文件底部留下空白行.
如何在保存时修剪它们?

UPDATE

谢谢大家,所有解决方案似乎都有效
不幸的是,它们都重置当前光标位置,所以我写了这个函数

function TrimEndLines()
    let save_cursor = getpos(".")
    :silent! %s#\($\n\s*\)\+\%$##
    call setpos('.', save_cursor)
endfunction

au BufWritePre *.py call TrimEndLines()
Run Code Online (Sandbox Code Playgroud)

Pri*_*ash 31

这个替换命令应该这样做:

:%s#\($\n\s*\)\+\%$##
Run Code Online (Sandbox Code Playgroud)

请注意,这将删除仅包含空格的所有尾随行.要仅删除真正的"空"行,请\s*从上面的命令中删除.

编辑

说明:

  • \( .....开始一个匹配组
  • $\n ...匹配一个新行(行尾字符后跟回车符).
  • \s* ...在这个新行上允许任意数量的空格
  • \) .....结束比赛组
  • \+ .....允许该组出现任意数量(一个或多个).
  • \%$ ...匹配文件的末尾

因此,正则表达式匹配仅包含空格的任意数量的相邻行,仅由文件末尾终止.然后,substitute命令将匹配替换为空字符串.

  • 另一种模式是`/\_ s*\%$` (5认同)
  • @Benoit:请注意该模式,因为它会导致删除最后一个非空行上的尾随空格,这可能是不合需要的. (3认同)
  • @Merlyn Morgan-Graham:`#`是模式分隔符.您可以选择使用`s`命令的地方,`/`不是必需的. (2认同)

ib.*_*ib. 13

一个优雅的解决方案可以基于:vglobal命令(或者,在:globalwith !修饰符上是相同的),

:v/\_s*\S/d
Run Code Online (Sandbox Code Playgroud)

此命令:delete在每个没有非空白字符的行上执行,然后在剩余文本中执行到缓冲区末尾.因此,该命令删除拖尾空行.

要在缓冲区末尾删除空行(严格意义上,而不是只包含空格的空行),请:vglobal按如下所示更改该命令中的模式 .

:v/\n*./d
Run Code Online (Sandbox Code Playgroud)

在包含大块连续空白字符的大型稀疏文件(从大约几百千字节的空白开始)上面的命令可能具有不可接受的性能.如果是这种情况,可以使用相同的优雅想法将该:vglobal命令转换为更快的范围删除命令.

对于空行:

:0;/^\%(\_s*\S\)\@!/,$d
Run Code Online (Sandbox Code Playgroud)

对于空行:

:0;/^\%(\n*.\)\@!/,$d
Run Code Online (Sandbox Code Playgroud)

两个命令的本质是相同的,即删除属于指定范围的行:delete.范围根据以下三个步骤定义:

  1. 在解释范围的其余部分之前,将光标移动到缓冲区的第一行(0;请参阅参考资料:help :;).01行号之间的区别在于前者允许在第一行匹配,此时在该范围中稍后使用搜索模式.

  2. 搜索描述非拖尾空行(\_s*\S\n*.)的模式不匹配的行(否定是由\@! 原子引起的).将范围的起始行设置为该行.

  3. 将范围的结束行设置为缓冲区的最后一行.

要在保存时运行上述命令之一,请使用BufWrite事件(或其同义词BufWritePre)上的auto-command触发它.

  • 这不仅更优雅,而且功能更强大.人们有时会混淆掌握某些东西的价值,这不是通过过度设计你有限的知识子集,而是从你的工具能够提供的功能中学习新的可能性. (3认同)

Ben*_*oit 8

你可以把它放到你的vimrc中

au BufWritePre *.txt $put _ | $;?\(^\s*$\)\@!?+1,$d
Run Code Online (Sandbox Code Playgroud)

(替换*.txt为你想要的任何globbing模式)

详情:

  • BufWritePre 是将缓冲区写入文件之前的事件.
  • $put _ 在文件末尾添加一个空行(来自始终为空的寄存器)
  • | 链Ex命令
  • $;?\(^\s*$\)\@!?转到文件末尾($)然后(;)查找向后(?…?)第一行不完全为空(\(^\s*$\)\@!),也查看:help /\@!vim搜索中的否定断言.
  • ×××+1,$ 形成从行×××+ 1到最后一行的范围
  • d 删除行范围.