为什么我不能使用 Shift+箭头键在 Linux 终端仿真器中突出显示文本?

为什么我不能使用 Shift+箭头键在 Linux 终端仿真器中突出显示文本?

这些是我在终端仿真器以外的任何 Linux 应用程序中编辑文本时经常使用的标准文本编辑键盘快捷键:

  • +箭头向左+向右移动
  • ctrl+ctrl+移动整个单词
  • home/end移动到行首/行末
  • ctrl+ c/ ctrl+v复制/粘贴 [某些终端可以使用shift+ ctrl+ c/ shift++ ctrlv这是一个很好的替代品]
  • shift+shift+突出显示文本
  • shift+ ctrl+shift+ ctrl+突出显示整个单词

我从未发现过可以实现此列表中最后两项的 shell 和终端仿真器组合,这让我很抓狂。显然,终端仿真器支持突出显示(鼠标可以实现),并且支持使用ctrlshift键作为修饰键(它们可以分别用于将光标移动整个单词和将字母大写;[编辑:] 它们甚至可以一起使用来复制/粘贴shift+ ctrl+cshift+ ctrl+ v),那么是什么问题阻碍了此功能?我有几个问题:

  • 这是我的终端仿真器的问题,还是我的 shell(bash,虽然我愿意更改)的问题?
  • 为什么终端仿真器/shell 不符合这个通用标准?
  • 如果确实有原因,那么它是否古老而过时,或者对于相当一部分人来说仍然有意义?桌面Linux 用户?
  • 有没有什么解决方法?
  • 是否有一些不太知名的程序可以支持此功能?
  • 修改 gnome-terminal 的源来支持这一点是否可行?

我知道可以用鼠标复制/粘贴文本,但这不是我要问的。我问的是为什么我不能用终端仿真器中的键盘做这些事情。

答案1

我认为如果我一次解决一部分问题会最有用。一般问题是:按键是针对谁的?终端,还是终端内运行的程序?

例如,“screen”是一种终端,它使用Ctrl+A作为命令的前缀,以区别于正在运行的程序本身。(并提供了一种发送Ctrl+的方法A。)

gnome-terminal有几个键,它可以捕获并执行各种操作,包括您询问的一些操作。

还请记住终端的“突出显示”与终端的光标位置是分开的. 有些终端根本没有突出显示功能。

现在,一次使用以下组合键:

左+右箭头移动 左+右 ctrl+箭头移动整个单词 home/end 移动到行首/行末

向左和向右移动什么?可以配置 Bash 来执行此操作,并且通常是默认的。通常,这些会移动光标位置。

ctrl+c/ctrl+v 复制/粘贴

首先:复制/粘贴有意义吗?如果你在 VT,你实际上没有剪贴板,尤其是在 X 没有运行时。

有些终端可以复制输出中的文本,有些终端还会通过模拟您输入剪贴板内容来“粘贴”。例如,++Ctrl是粘贴,这可能会有所帮助。(而++是复制。)如前所述,+和+ 的最大问题是它们与常见的终端/程序命令重叠。(+是发送中断(SIGINT),而+是逐字的。)ShiftVgnome-terminalCtrlShiftCCtrlCCtrlVCtrlCCtrlV

一些终端还支持两种复制数据的模式:更常见的“仅复制”和所谓的“块选择”或“块复制”。(例如,按住Ctrl,然后在其中拖动。)gnome-terminal

此外,xsel -b还可用于将剪贴板内容通过管道传输出去。取决于具体情况,xsel终端的粘贴版本是否更有用。请参阅man xsel

shift+箭头突出显示文本 shift+ctrl+箭头突出显示整个单词

您的终端的突出显示(如果它具有此功能)与光标位置是分开的。同样,缺少可用的组合键可能是一个因素。请记住,突出显示有两个位置:开始和结束,或左上角和右下角。您如何管理这两个位置?

最后,请注意,在许多 GUI 终端中,双击一个单词将会突出显示它。(在 X 中,复制到主要选择。)

screen例如,有键可以切换到在缓冲区(先前的输出)中移动以及复制/粘贴的模式。

我认为,如果您充分利用xsel和主要选择,您会发现剪贴板操作既足够少见又足够复杂,值得使用鼠标。

答案2

正如塔纳托斯所提到的,终端仿真器(在 X Windows 或 Wayland 上运行)和终端内运行的程序(我们称之为“壳”,尽管它可能不是);这两个东西是相互隔离的(见技术细节)。

列表中的第一项(箭头键、Home/End 等)由终端内的程序直接处理,因此光标位置由终端内部的程序控制。

另一方面,复制和粘贴快捷键(Ctrl+Shift+C 和 Ctrl+Shift+V)由终端仿真器处理,它可以理解鼠标(因此您可以用鼠标选择文本),它知道屏幕上的内容(因此它可以复制),并且可以将按键发送到内部程序(因此它可以粘贴)。

为了支持 Shift+Left 和 Shift+Right,终端仿真器或 shell 必须处理按键。无论哪种方式,我们都会遇到一个问题:

  1. shell 无法轻松处理这些键,因为最终你会想要将选定的文本复制到剪贴板,而剪贴板是一个 X Windows 概念,shell 不一定有权访问它(但请参阅xclip)。而且据我所知,如果 shell 支持文本选择,Linux 并没有定义任何机制来通知终端仿真器选择了什么。
  2. 同时,终端仿真器不负责光标的位置。即使终端仿真器可以更改光标的位置,它也可能不知道当前文本行的开始和结束位置。例如,终端可能包含类似这样的文本,~ $ ls -l而终端仿真器不知道只有该ls -l部分属于用户。

不难想象一个支持使用 Shift+Arrows 进行选择的终端仿真器,但我猜它必须隐藏 shell 的光标并引入自己的“假光标”,该光标暂时存在以帮助您选择某些内容,然后您可以按 Ctrl+C / Ctrl+Shift+C / Ctrl+Ins 进行复制(或按 Esc 取消)并再次显示真实光标。当然,这不会具有正常选择的所有功能 - 特别是不存在剪切和删除。

答案3

我不是终端仿真器专家,但是......

运行到终端仿真器中的 bash(readline)等应用程序对正在运行的 X 窗口系统及其所在的 X 窗口一无所知,它们知道终端设备上的 stdin 和 stdout(linux 上的 ttyS/ttyUSB/tty/pts)。

问题不在于显示一些突出显示的文本但是如何让 X 窗口应用程序(终端仿真器)知道文本已被选中,通过这些终端设备。

猜测X 终端应用程序在输入和输出中打开其中一个设备,然后将 X 键事件转换为正确的输出(从 X 侧)输入(从 bash 端)。反之亦然输出流到 X 终端输入,这里 X 终端处理这个输入来移动光标,用一些颜色填充背景,与 bash 应用程序的输出一致。

据我所知,转义码可用于控制特殊行为,如清除、填充背景、移动光标等或许一些风俗可以添加转义代码,让 X 终端知道文本从 行,列 到 行,列已被选中,仅仅是一个例子,也许可以返回所选的文本(一个实现细节)。

猜测这不是标准定义,您必须修补每个要支持的应用程序,以便它知道按下的键组合并输出适当的转义码,如果您希望在 bash 中使用 readline,另一侧的 X 终端仿真器可以正确处理转义码(并最终将信息发送到剪贴板)。可能将其实现为终端能力可以让你免去对每个应用程序打补丁的麻烦。我希望(并且猜测)内核中的终端设备驱动程序对转义码了解得越少越好,所以如果你足够幸运的话,就不需要打补丁了。

X 终端绘制输出,因此当您使用鼠标时,它很容易知道您选择了什么文本/字符。

图形文本小部件了解其 X 窗口的一切,因此可以如此轻松地实现选择和复制。

编辑

这里,这个 urxvt-9.16-image-display 补丁可以作为了解支持新转义代码所需的内容的一个很好的起点。 http://lists.schmorp.de/pipermail/rxvt-unicode/2013q1/001736.html

答案4

这些是您描述的 CUA 键盘绑定,是 IBM 在 80 年代中期制定的标准:

https://en.wikipedia.org/wiki/IBM_Common_User_Access

它们通常应用于此后创建的所有桌面环境。DOS、Windows、Motif 甚至 Netware 工具都遵循此标准。Mac 是例外,它使用同一时期非常相似但不同的一组键(Cmd 而不是 Ctrl)。

然而,Unix 终端(以及后来的模拟器)远早于此标准,并且大多忽略了它。此外,如果他们确实实现了这些键绑定,它可能会干扰已经将它们用于其他功能的 TUI 程序。因此,虽然技术上可行,但也存在问题。

应用:

micro文本编辑器是我见过的模拟 GUI 文本编辑器中最好的,类似于 DOS  edit,但具有更多现代功能,如 Sublime Text。 ne是 Debian 存储库中较旧的版本,甚至nano可以配置合理的键绑定。但裸终端/shell 不行。

使用libvte它,您可以轻松构建一个基本的虚拟终端来自己处理这些键绑定。然而,这需要付出很多努力才能获得微小的收益。

相关内容