从控制台复制时尾随空格

从控制台复制时尾随空格

这是我偶尔遇到的这种烦人的行为:当您在控制台中用鼠标选择文本(即复制它)、粘贴它时,您会发现每行末尾都有多余的空格。那是,

line 1                                                                          
line 2                                                                          

代替

line 1
line 2

因此,每行末尾不仅仅是一个空格。

我无法可靠地重现该问题,也找不到答案。我相信对于某些软件来说,它只会在一段时间后显现出来。

但我刚刚注意到,当我在 中打开相同的文件时vim,首先从控制台,然后从tmux,在前一种情况下效果很好。而后一种则不然。考虑到TERM=xterm-256color在控制台和TERM=screen-256colortmux,我的猜想是,这与终端未正确执行此操作或未使应用程序正确执行此操作有关。我认为这是一个相当模糊的猜想。所以,第一个问题是,“到底是什么造成的?”

另一个问题是“我该怎么做?”最坏的情况是文件位于远程。我以前是复制到本地然后用最近打开的gedit。现在我应该可以选择在新控制台中打开它(因为我主要在tmux会话中工作),然后从那里复制。这可以做得更简单吗?

当我vimtmuxwith运行时TERM=xterm-256color vim,它的行为很奇怪。就像没有文字的地方不绘制背景一样。对我来说,更改变量似乎不太合适TERM(让软件认为它正在处理其他终端)。

当编辑本地文件时,我通常这样做:!gedit %

答案1

如果应用程序在该位置显示空格,则从终端进行选择和复制时,您将在行尾看到空格。应用程序可能会显示空格以删除之前的内容。终端有删除整行或删除光标右侧字符的命令;应用程序根据他们认为最有效的方式在显示空间和显示空间之间进行选择。例如,如果您在提示符处输入一些内容,然后按 Backspace,应用程序(例如 shell)可能会用空格覆盖最后一个字符。

如果您有 X11 连接,则可以使用xselxclip将文件复制到本地剪贴板。

实验上,Vim 似乎费尽心思不显示以空格结尾的行(即使缓冲区包含以空格结尾的行)。因此,如果您没有 X11 连接,则可以选择从中复制。

另一种方法是在复制后进行后处理:

xsel | sed 's/  *$//' | xsel

答案2

这实际上是几个问题,没有一个答案只是略过有趣的部分:

  • 当您在控制台中用鼠标选择文本(即复制它)并粘贴它时,您会发现每行末尾都有额外的空格。
  • 当我使用 TERM=xterm-256color vim 从 tmux 运行 vim 时,它的行为很奇怪。

大多数终端(如 xterm)存储您可以选择的数据屏幕。它后面没有隐藏的部分告诉终端该应用程序旨在填充背景。

应用程序通过移动光标、写入文本(可能包括实际的空格或终端上显示的选项卡)来更新屏幕。渲染作为空格)并擦除屏幕的部分内容。

擦除是一个特殊问题(对于选择/粘贴),因为许多终端(例如 xterm)将充满屏幕上当前颜色的已擦除区域(终端说明中的背景颜色擦除 (bce) 功能)。但与此同时,已擦除区域不再在屏幕的这些位置存储字符。使用屏幕表示的终端将允许您选择除擦除区域之外的所有内容。 (作为特殊情况,您的终端可以删除了文本包围的区域,它会假装是可供选择的空间)。

所有这些都很麻烦,很久以前 xterm 提供了忽略尾随空格的功能。大多数其他终端不提供此功能。由于它是一个选项,如果您碰巧运行 xterm,它可能不会打开。大多数复制 xterm 功能的终端开发人员不会复制选项。

转到 tmux:它不支持 bce 功能。它的开发者决定不这样做。因此,在 tmux 中运行的普通应用程序将产生尾随空白。当您覆盖终端描述时,它会使 tmux 感到困惑,因为它不知道 vim 确实假设背景将被清除使用当前颜色。您只需删除即可。没有颜色。

另一方面,GNU screen 的开发人员不久前就决定支持该功能。这是可选的...

进一步阅读:

  • 支持背景颜色擦除 (bce) [原: Vim 复制粘贴尾随空格问题] #109(tmux 错误报告)
  • 我的终端显示一些未着色的空间(ncurses 常见问题解答)
  • 终端的问题(关于该主题的有用讨论)
  • highlightSelection(xterm 手册)
  • trimSelection(xterm 手册)

    如果设置highlightSelection,您可以看到选定的文本,包括任何尾随空格。清除屏幕(或一行)会将其重置为不包含空格的状态。当应用程序将某些行写入屏幕时,某些行可能包含尾随空格。但是,您可能不希望粘贴带有尾随空格的行。如果此资源为 true,xterm 将从所选文本中删除尾随空格。它不会影响导致换行的空格,也不会从您的选择中修剪尾部换行符。默认值为“假”。

  • 补丁 #105 - 1999/6/5 - XFree86 3.9Pp(xterm 变更日志)

    实施新资源trimSelection,它允许 xterm 修剪所选行中的尾随空白。这不会影响突出显示。

  • 补丁 #27 - 1996/8/21 - XFree86 3.1.2Ek(xterm 变更日志指的是highlightSelection

    这个补丁解决了我长期的抱怨之一:xterm 的选择没有清楚地显示所选择的内容(根据 David 的要求,它由资源控制,默认为旧行为)。

答案3

从终端屏幕复制和粘贴永远不会完全可靠,因为它处理的是屏幕输出而不是原始源材料。如果某些应用程序以不寻常的方式将文本回显到终端,并导致终端无法猜测原始文本是什么,那么您或终端可能对此无能为力。

当原始文本呈现到终端时,许多有关原始文本的信息可能会丢失:例如,空白区域是由制表符还是一系列空格生成的,或者两行文本最初是否是一个长文本被包裹的线或两条单独的线。

终端会尽力让您复制并粘贴回显到终端的原始文本,但它并不总是知道。

作为一个实验,试试这个:

  • 用于less查看包含跨多个终端行的很长行的文件。
  • 三击其中一行(选择整行)。less选择跨越多条物理线的整个逻辑线,如果将其粘贴到其他地方,它将保留为一根长线。
  • j一些行数,以便部分那条长线的一部分从屏幕顶部消失了。
  • k一次或多次可将整个逻辑行滚动回视图中。
  • 再次三次单击逻辑线。这次只选择了一条物理线路。这是因为less逐条物理线重新绘制了屏幕物理线,并且终端不再有任何方式知道物理线已连接在一起。
  • 现在,如果您手动拖选整个逻辑行并将其粘贴到其他位置,您会发现它嵌入了换行符。

YMMV 对该实验进行了评价,因为您的终端(或 的版本less)可能比我的更聪明或更不聪明。

一般来说,生成输出的软件越笨,您能够准确复制和粘贴原始材料的机会就越大。 cat一方面,这几乎是愚蠢的。(你当然明白“笨”是一种恭维!)

如果您在 下的行末尾看到额外的空格字符tmux,则可能是因为tmux实际上是回显该字符。请记住,它tmux会进行自己的终端仿真,然后重新发出新的终端序列以呈现到底层终端。也许它正在呼应该空格字符,因为它认为在某些情况下可能需要覆盖它认为可能存在的其他字符。无论什么原因,终端可能无法知道空格字符实际上不是原始内容的一部分。

答案4

使用 Fedora 17 Linux 和 konsole 终端窗口,我使用 syntastic vim 插件打开 vim,我能够一致地重现此错误。我将这三行Python代码放入vim中:

a = "generic assignment"
b = "cursor is on this line"
c = "generic assignment"

然后我直观地选择这些行并将其粘贴到此处:

a = "generic assignment"
b = "cursor is on this line"                                                                                     
c = "generic assignment"

请注意第二行如何复制大量空格。这肯定会让人厌烦。

第 1 行和第 3 行按预期复制,但第二行复制空格,直到终端窗口的最右边位置。

解决方案:

在用鼠标选择之前,将突出显示的行(vim 光标)移离要复制的行。那么多余的空格就不会出现在这一行上。

我猜是语法和颜色突出显示插件导致了这些问题。

相关内容