从另一个命令行驱动的软件中,我习惯了以下行为:向上/向下箭头浏览命令历史记录,匹配与当前行上迄今为止输入的字符匹配的行,然后 Esc 删除当前行上迄今为止输入的所有内容。我试图让 bash(通过 readline)做同样的事情。这是我在 .bashrc 中输入的内容:
bind 'Escape: kill-whole-line'
bind '"\e[A": history-search-backward'
bind '"\e[B": history-search-forward'
由于 Escape="\e" 的映射与转义序列“\e[A”和“\e[B”的映射相互干扰,因此该行为不符合预期。
我的问题:有没有办法让它工作?一种可能性是基于时间的,即如果 \e 后面紧跟着另一个键,它将被视为序列的一部分,但如果在短暂的延迟期间没有其他任何内容,它将被视为单独的键。但是,阅读 bash 和 readline 文档后,我无法想出这样的方法。
附带问题:是否存在一种现代终端“模拟器”,它实际上并不试图模拟历史机器的复杂行为,而是为在其中运行的程序提供有关所按按键的明确信息?它还可以区分 CTRL-A 和 CTRL-SHIFT-A……我在 KDE 的 Konsole(其行为类似于 xterm)和 Linux 控制台上测试了这些东西。
答案1
如果您正在使用xterm
,您可以通过设置 eightBitControl 布尔资源让它发送CSI
(0x9B) 而不是序列\e[
。例如,像这样启动 xterm:
xterm -xrm '*eightBitControl:true'
您可以通过编辑 XTerm 应用程序特定的资源文件来永久设置此资源(Ubuntu 似乎将其放入/etc/X11/app-defaults
但我认为/usr/share/X11/app-defaults
更标准。)
但请注意:这会基本上破坏您的终端,直到您修复所有键绑定。
至于更一般的问题,我认为它比乍一看更难。Linux 控制台在生成八位字符代码方面设计得相当好(因此它可以与 UTF-8 一起使用)。从实际控制台(即不使用 X)中,您可以获得“原始”扫描码,但随后您必须自己完成所有键映射逻辑(事实上,这正是 X 所做的)。您可能能够使用 X 键映射功能为 alt+ctrl+字母组合生成一些特定代码,但我不知道您会将它们压缩到八位编码序列中的哪个位置。不过,我理解您的痛苦 :)