【问题标题】:Why do gedit and vim hide the final newline from the user?为什么 gedit 和 vim 对用户隐藏最后的换行符?
【发布时间】:2013-10-14 22:13:46
【问题描述】:

假设我们有两个文本文档:

  1. 我们的第一个文件包含“@​​987654321@”作为文本。
  2. 我们的第二个文件包含“@​​987654322@”作为文本。

当我们在 gedit、vi 或 vim 中打开这两个文件时,这两个文件在各个方面在视觉上都是相同的。

但是,当我们对文件运行 xxd 时,我们会得到以下信息:

  1. 我们第一个文件的十六进制内容为:6869
  2. 第二个文件的十六进制内容为:6869 0a

啊哈!有一个看不见的换行符。在 vim 中,如果我们足够关注状态栏并且碰巧理解 [noeol] 的含义,那么我们可能会理解这一点,但在 gedit 中,两个文件打开时完全相同!

在一项小型调查中,当我要求人们仅使用 gedit 或 vim 来区分这两个文件时,他们 100% 的时间都失败了。当我要求他们使用 Leafpad 或 emacs 完成相同的任务时,他们 100% 成功。

我知道 vi 和 gedit 想要在他们创建的每个文件中添加一个换行符(我承认这样做可能有好处)。我不明白为什么 gedit 和 vim 认为在视觉上对用户隐藏这个换行符是有益的?尤其是当这种行为具有潜在的极度破坏性......

(例如,两个 C 程序员在他们的 vi/gedit 文本编辑器中看到这两个文件的内容相同,然后假设他们看到的是他们得到的,继续将内容写入数组char greeting[2]. 第一个编写第一个文件的程序员 - 虽然他的代码有点草率 - 继续名利双收,但第二个编写第二个文件的程序员死于悲惨的贫困中,被这种无形的(并且可以预防的)困惑和困惑) 堆栈溢出。)

所以请告诉我,像 vim 和 gedit 这样的文本编辑器在他们创建的每个文档的末尾添加不可见的换行符有什么好处,然后继续对用户隐藏这些换行符,以便这些文件的真实内容只有使用其他文本编辑器才能明显检测到?

【问题讨论】:

  • 如果你想用变量“require-final-newline”,Emacs 会自然地添加一个最终的换行符。我认为也有一种特定于模式的方法。通用编辑器将字节添加到您没有要求的文件中似乎相当冒昧,但是如果 Vim 仅打算在 Unix 系统上用于编写特定类型的文件,那么也许这是不公平的称它为通用编辑器。

标签: vim emacs newline vi gedit


【解决方案1】:

您认为最后一行“视觉上隐藏”源于相反的观点。

许多人(尤其是具有 Unix 背景的人)认为文本文件应该始终以换行符结尾(例如,参见 Why should text files end with a newline?),并且任何允许在没有它的情况下创建文件的文本编辑器从根本上被破坏了。从这个角度来看,Vim 中没有额外的空行只是符合这个世界观。该文件出现在编辑器中,就像它在终端中被cated 时一样。

从 Vim 的角度来看,缺少换行符的文件是异端和有缺陷的;这就是为什么它在加载时用 [noeol] 消息指示(并且在保留缺少的换行符的同时编辑文件非常困难;尽管我已经编写了 PreserveNoEOL plugin 来帮助解决这个问题)。

【讨论】:

  • 来自 Windows 背景,您的回答有助于阐明 unix 文本编辑器/文本文件的期望,谢谢。但是我不认为“视觉上隐藏”可以仅仅作为一个观点而被忽视(即,如果两个不同的文本文件在用户的眼睛上显示相同,那么客观地说 - “视觉上隐藏”)。如果 vi 在它创建的每个文件的末尾显示一个不可修改的空白行,它将满足您对 unix 文本文件/文本编辑器的期望,同时还为遇到没有最终换行符的文本文件的用户提供对比鲜明的视觉表示。
  • @schulwitz,为什么 Vim 应该显示一个不存在的行,就好像它存在一样?那么如何改正对 EOL 字符的所有错误解释呢?并且用户可以完美地查看最后一行是否没有以状态行中带有[noeol] 的 EOL 结尾。
  • 谢谢。从“Unix 角度”来看,这两个文件实际上是相同的(它们将在第一个 :write 命令之后)。从这个角度来看,根本不值得关心这些差异。你是对的,虽然这会在与“另一个世界”互动时引起摩擦。
  • @romainl “用户可以完美地查看最后一行是否以状态行中带有 [noeol] 的 EOL 结尾。”正是我的观点,如果唯一能在视觉上区分一个文件与另一个文件的东西是在状态栏中,那么您的视觉设计未能向用户传达适当的含义。
  • 我不同意。文本文件的最后一行应该以 EOL 字符结尾:这很正常,而且有意义。没有意义的是在文件的最后一个字符 之后显示一个空行,而 Vim 正确地避免了这样做。 EOL 的出现是正常的,也是意料之中的,所以没有什么特别的显示!当它遇到一个没有 EOL 的文件时,Vim 会很有帮助地警告你。您如何表示没有 EOL?最后一行末尾的符号?如果最后一行是#4325 而你看不到它怎么办?状态栏显然是唯一明智的解决方案。
【解决方案2】:

我相信这是从 vi 继承而来的约定。这样做的一个好处是,在连接文件时,您仍然可以区分每个文件的结束位置。

提供了更多上下文in this thread on the vim_use mailinglist

【讨论】:

  • 我理解(并承认)结束换行符有好处。我不明白的是为什么这在视觉上对用户隐藏? (即在 vim 中,最后的换行符没有视觉表示,而是出现 ~ ,好像文件中没有任何内容。但是,vim 中的每个其他换行符都有一个空行来指示它的存在,为什么不是最后一个? )
  • @schulwitz,没有显示空行,因为它不存在。 EOL 字符通常以两种方式解释:“必须将任何在我之后的内容视为在新行中”和“在我之后出现新行”。大多数 GUI 文本编辑器/IDE,无论有无 UNIX 背景,都遵循第一个(错误的):EOL 之后的内容被视为一行,编辑器将其显示为这样,即使“线”没有满足。大多数 UNIX 文本编辑器都遵循第二个:因为在最后一个 EOL 之后什么都没有,所以没有什么可显示的。
  • 我认为这只是对概念的不同看法。在 Unix 世界中,最后的换行符被认为是 line terminator 而在 Windows World 中似乎认为它是 line separator 因此从 line terminator 观点,根本没有对用户隐藏的最终新行。
  • 我喜欢你的回复,Christian,我将其改写为:在 Vim 对 EOL 字符的概念视图中,当文件末尾没有 EOL 时,只有一个不完整的行,因为它没有 EOL。使用 EOL,仍然只有一条线路,并且已正确终止。在其他编辑看来,当文件末尾没有 EOL 时,则文件中有一行,该行没有什么特别之处。当文件末尾有 EOL 时,有两行由 EOL 隔开,最后一行为空。
猜你喜欢
  • 2010-09-09
  • 1970-01-01
  • 2010-09-06
  • 1970-01-01
  • 2021-08-08
  • 1970-01-01
相关资源
最近更新 更多