如何阻止vim在文件末尾添加换行符?

我在一家PHP商店工作,我们都使用不同的编辑器,我们都必须在Windows上工作。我使用vim,但是店里的每个人都在抱怨,每当我编辑一个文件时,在底部有一个换行符。我四处搜索,发现这是vi &vim……但我想知道是否有办法禁用这个功能。(这将是最好的,如果我可以禁用特定的文件扩展名)。

如果有人知道这事,那就太好了!

133950 次浏览

我没有尝试过这个选项,但在vim帮助系统(即帮助eol)中给出了以下信息:

'endofline' 'eol'   boolean (default on)
local to buffer
{not in Vi}


When writing a file and this option is off and the 'binary' option
is on, no <EOL> will be written for the last line in the file.  This
option is automatically set when starting to edit a new file, unless
the file does not have an <EOL> for the last line in the file, in
which case it is reset.

通常你不需要设置或 重置此选项。当'binary'是 Off该值在写入时不使用 该文件。当'binary'在上面时,它就是 用来回忆曾经的存在 对于文件的最后一行, 当你写入文件时 情况从原始文件可以 (被)保持。但你可以改变,如果你 想。< / p >

你可能对前面一个问题的答案也感兴趣:"为什么文件应该以换行符结束"。

也许你可以看看他们为什么抱怨。如果一个php文件在结尾?>后面有换行符,php将把它作为页面的一部分输出。这不是问题,除非您尝试在文件包含后发送头文件。

但是,php文件末尾的?>是可选的。没有结尾?>,在文件末尾使用换行符没有问题。

您是否可以使用一个特殊的命令来保存这些文件?

如果您执行:set binary,:w和:set nobinary,则如果文件开始时没有换行符,则写入文件时将不带换行符。

当然,这个命令序列可以放入用户定义的命令或映射中。

在你的.vimrc中添加以下命令来打开行结束选项:

autocmd FileType php setlocal noeol binary fileformat=dos

然而, PHP本身将忽略最后一行结束-这应该不是一个问题。我几乎可以肯定,在你的情况下,有其他东西添加了最后一个换行符,或者可能与windows/unix的行结束类型(\n\r\n等)混淆。

更新:

另一个解决方案可能是在你的.vimrc中添加这一行:

set fileformats+=dos

好吧,你在Windows上让事情变得复杂了;)

由于'binary'选项将重置'fileformat'选项(使用'binary'设置写入总是使用unix行结束符写入),让我们拿出大锤子并从外部完成它!

为BufWritePost事件定义一个自动命令(:help autocommand)怎么样?每次写入整个缓冲区后都会执行此自动命令。在这个自动命令中调用一个小的外部工具(php, perl或任何脚本),剥离刚刚写入的文件的最后换行符。

它看起来就像这样,会进入你的。vimrc文件:

autocmd!   "Remove all autocmds (for current group), see below"
autocmd BufWritePost *.php !your-script <afile>

如果这是您第一次使用自动命令,请务必阅读关于自动命令的完整vim文档。有一些注意事项,例如,建议删除你的.vimrc中的所有autocmd,以防你的.vimrc可能被多次引用。

我在Vim wiki上添加了一个类似(尽管不同)问题的提示:

http://vim.wikia.com/wiki/Do_not_auto-add_a_newline_at_EOF

如果使用Git进行源代码控制,还有另一种方法。受到答案在这里的启发,我编写了自己的过滤器用于gitattributes文件。

要安装这个过滤器,将其保存为noeol_filter在你的$PATH的某个地方,使其可执行,并运行以下命令:

git config --global filter.noeol.clean noeol_filter
git config --global filter.noeol.smudge cat

要开始仅为自己使用过滤器,在$GIT_DIR/info/attributes中放入以下行:

*.php filter=noeol

这将确保你不会在.php文件的eof处提交任何换行符,无论Vim做什么。

现在,脚本本身:

#!/usr/bin/python


# a filter that strips newline from last line of its stdin
# if the last line is empty, leave it as-is, to make the operation idempotent
# inspired by: https://stackoverflow.com/questions/1654021/how-can-i-delete-a-newline-if-it-is-the-last-character-in-a-file/1663283#1663283


import sys


if __name__ == '__main__':
try:
pline = sys.stdin.next()
except StopIteration:
# no input, nothing to do
sys.exit(0)


# spit out all but the last line
for line in sys.stdin:
sys.stdout.write(pline)
pline = line


# strip newline from last line before spitting it out
if len(pline) > 2 and pline.endswith("\r\n"):
sys.stdout.write(pline[:-2])
elif len(pline) > 1 and pline.endswith("\n"):
sys.stdout.write(pline[:-1])
else:
sys.stdout.write(pline)

对于vim 7.4+,你可以使用(最好是在你的.vimrc上)(感谢罗泽轩的最后一点新闻!):

:set nofixendofline

现在关于vim的旧版本。

即使文件已经保存,在最后添加新行:

< p > vim -b file 一旦在vim:

:set noeol
:wq

完成了。

或者你可以用:e ++bin file在vim中打开文件

还有另一种选择:

:set binary
:set noeol
:wq

详见为什么我需要vim在二进制模式'noeol'上班吗?

我已经用Perl和Python后处理实现了Blixtor的建议,要么在Vim内部运行(如果它是用这种语言支持编译的),要么通过外部Perl脚本运行。它可以在vim.org上以PreserveNoEOL插件的形式获得。

尝试添加. vimrc

set binary
我想我找到了一个比公认答案更好的解决办法。其他的解决方案都不适合我,我不想一直在二进制模式下工作。 幸运的是,这似乎完成了工作,我还没有遇到任何讨厌的副作用:保留文本文件末尾缺少的行尾。我只是把整个东西添加到我的~/.vimrc.

我发现这个vimscript插件对这种情况很有帮助。

Plugin 'vim-scripts/PreserveNoEOL'

或者在github阅读更多

你可以从vim v7.4开始使用

:set nofixendofline

这里有一些关于这个变化的信息:http://ftp.vim.org/vim/patches/7.4/7.4.785