通过 .inputrc 将 Ci 和 TAB 键绑定到终端应用程序中的不同命令

通过 .inputrc 将 Ci 和 TAB 键绑定到终端应用程序中的不同命令

对于我所尝试的,TABC-i.inputrc 中似乎意味着同样的事情,无论我绑定到一个,都会绑定到另一个。我知道最初是同一件事,而且这种行为是从旧时代继承下来的,但现在,除了终端仿真器之外,所有 X 应用程序都区分了 aC-iTABpress。

那么有没有办法在我按下该TAB键时运行终端命令(例如“完成”)并在按下时运行另一个命令C-i

(同样的问题适用于C-mENTERC-zC-d以及所有这些控制序列,我想通过原始绑定之外的其他方式发送这些控制序列,并将我自己的命令应用于这些珍贵的键绑定)

顺便说一句,如果你能解释一下从按键到 shell 解释的过程,这将有助于我理解。现在我明白键盘事件由 Xmodmap 翻译,然后由 .inputrc 翻译,结果由 shell 或类似的东西解释。

我目前使用 Guake,有时还使用 gnome-terminal 作为终端模拟器。

在遵循评论中提出的链接后,终端仿真器似乎是将TABkeysym 从 X 服务器转换为C-i并将其发送到 bash shell 的链的元素,因为它不理解诸如TABENTER和同级之类的东西。因此,配置 readline 本身将不起作用,因为它位于终端模拟器之后、bash shell 之前。那么问题可以这样精确:如何配置我的终端模拟器,以便将TABand C-iENTERandC-m等转换为不同的字符序列对?也许制作TABENTER发送一个新的自定义转义序列,该序列可以稍后在 .inputrc 中映射到原始命令,并最终能够用于C-i其他C-m目的。或者离开TABENTER制作C-iC-m发送转义序列。

答案1

终端模拟器将“Tab按键被按下”等事件转换为终端中运行的应用程序(在您的情况下为 bash)读取的字符序列。看键盘输入和文本输出如何工作?有关此主题的更详细介绍。

Ctrl由于历史原因,一些键发送的字符与按下其他字符相同: Tab= Ctrl+ IReturn= Ctrl+ MEsc= Ctrl+ [。这是因为历史物理终端这样做了,所以在终端中运行的应用程序期望它,所以终端这样做。

Guake 和 Gnome 终端都使用VTE图书馆,这不允许配置从键和弦到字符序列的映射。你有同样的问题bash - 与 control+alt+space 的键序列绑定错误

Xterm具有完全可配置的键绑定。您可以让Tab按键发送制表符(这是默认值),或者让它发送字符串hello,或者您选择的任何内容。 Xterm 配置通过X资源。例如,要在按下和释放时Tab发送转义序列,请将其放入您的:\e[t\e]t~/.Xresources

XTerm.vt100.translations: #override \
  <Key>Tab: string("\033[t") \n\
  <KeyRelease>Tab: string("\033]t") \n\

或者您可能会留下Tab发送制表符并 make Ctrl+I发送其他内容:

XTerm.vt100.translations: #override \
  Ctrl~Meta~Shift<Key>I: string("\033[a5i") \n\
  Ctrl~Meta Shift<Key>I: string("\033[a6i") \n\

然后,您可以\e[a5i使用可配置的键绑定绑定到 bash 和其他终端应用程序中您想要的任何内容。

请注意,按照惯例,多字符转义序列以转义字符开头(在编程语言和配置文件中通常表示为\eor\033\x1b);某些应用程序可能会遇到以其他字符开头的转义序列的问题,当然,您不能拥有一个既是转义序列又是其自己的键的字符,除非您愿意接受超时(这就是它在像 vi 这样的应用程序Esc本身就绑定了某些功能)。如果您定义自己的键序列,请注意不要与功能键和光标键发送的键序列冲突,这些键序列是或多或少事实上标准化

答案2

为了添加 Gilles 的出色答案,在 urxvt 终端模拟器中,也可以通过配置键映射.Xresources:例如,我将以下行添加到该文件中,以便与Ctrl+BackspaceCtrl+H比较这个问题),这样我就可以以不同的方式使用两个关键和弦:

# Map Ctrl+Backspace to little-used escape sequence
urxvt.keysym.C-BackSpace: \033[33~

之后我将以下内容添加到 my 中~/.zshkbd以使 zsh 区分两个关键和弦:

bindkey "^H" kill-line

# Ctrl + Backspace
bindkey "\033[33~" backward-delete-word

我相信对于zshCtrl+ITAB其他应用程序来说,它应该以类似的方式工作(尽管在这种情况下,显然会重新映射Ctrl+I到不同的字符)。

相关内容