什么是 bash 的元键?

Leo*_*Leo 18 bash keyboard-shortcuts xterm

我试图用来xmodmap映射META_LMENU键,但它似乎不被接受bash为元键。所以,我想知道这些组件(键盘、X、xterm、bash)如何与元键和超级键相关。任何解释将不胜感激。

让我换一种说法。例如,bash 手册页说,函数 yank-nth-arg 绑定到M-C-y并且当我按 时它可以工作Esc-Control-y。但是我觉得这有点麻烦。那么如何让 bash 接受另一个键作为Meta(如Menu)作为其所有默认绑定?

Gil*_*il' 13

从键盘键等改性剂的映射MetaControl由X服务器(即,GUI的低电平部分)来处理。可以通过旧式xmodmap命令或新式XKB界面,或通过在幕后使用其中之一的 GUI 配置工具来操作此映射。

默认情况下,在大多数设置中,Meta键是标记为 的键Alt。这是因为从历史上看,许多 unix 工作站都有一个键标记Meta,而 PC 的键标记为Alt。因此,如果您有 的绑定M-C-y,请按Ctrl+ Alt+ Y

要检查您当前的绑定是什么,请xev在终端中启动该程序。在 xev 窗口聚焦的情况下,按 键;您将在终端中看到生成的事件的记录。

终端仿真器(或物理终端对应的终端设备)和应用程序之间的通信使用字符。当您按下 时A,终端收到信息“A键,无修饰符”,但它发送给终端中运行的应用程序的是字符a。按Up或等功能键时F1,没有对应的字符;终端发送一个以转义字符开头的字符序列(字节 27,有时写成\e^[)。当诸如 xterm 之类的终端模拟器收到带有Meta修饰符的按键事件时,它会将该键转换为转义字符,后跟该键的底层功能,例如\ea(escape,小写 a) 当您按下Meta+ 时A

“终端”、“外壳”、“tty”和“控制台”之间的确切区别是什么?可能是有用的背景。


Ted*_*ddy 5

键事件由 X 服务器生成(由 配置xmodmap),并发送到您的 X 应用程序。您的窗口管理器可以在它被发送到 xterm 之前拦截它。反过来,XTerm 将事件转换为一些字节,并将这些字节发送到您的 shell bash 分配的伪 tty。

请注意,并非所有事件都由 XTerm 直接转换为字节。例如,Ctrlshift键本身会生成 X 键盘事件,但 XTerm不会向在其中运行的 shell(或其他应用程序)发送任何内容。这也包括Meta密钥本身,但不包括Menu密钥。但是,按下Meta-生成的事件e将使 XTerm 发送字节 0xE5 或两字节序列 0x1B 0x65,具体取决于 XTerm.VT100.metaSendsEscape 资源设置。


Tho*_*key 5

Bash 的元键最初是这样定义的(lib/readline/ChangeLog):

Mon Jul 13 11:34:07 1992  Brian Fox  (bfox@cubit)
        * readline.c: (rl_variable_bind) New variable "meta-flag" if "on"
        means force the use of the 8th bit as Meta bit.  Internal variable
        is called meta_flag.
Run Code Online (Sandbox Code Playgroud)

这恰好是ncursesxterm解释它的方式。提供了一些终端来使此功能成为可选(这方面并不普遍。您将遇到的大多数终端都使用硬编码行为(并且不是很有趣)。terminfo手册记录了这些终端功能:

   has_meta_key              km     km   Has a meta key
                                         (i.e., sets 8th-bit)
   meta_off                  rmm    mo   turn off meta mode
   meta_on                   smm    mm   turn on meta mode
                                         (8th-bit on)
Run Code Online (Sandbox Code Playgroud)

并解释了该功能:

如果终端具有充当移位键的“元键”,设置所传输的任何字符的第 8 位,则可以用 来指示这一事实km。否则,软件将假定第 8 位是奇偶校验位,并且通常会被清除。如果存在用于打开和关闭此“元模式”的字符串,则可以将它们指定为smmrmm

一些终端仿真器中并入了一个不同的功能,即在响应键时添加转义字符前缀Alt。Bash(实际上是库)在 2004 年的变更日志readline中记录了该用法:

lib/readline/callback.c            
        - use _rl_dispatch_callback and a chain of _rl_keyseq_contexts to
          simulate the recursion used to decode multicharacter key sequences
          (even things like ESC- as meta-prefix
Run Code Online (Sandbox Code Playgroud)

Meta 是修饰键的特例。与control和 一样shift,您与另一个键同时按下它,并期望看到与单独按下该键不同的东西。X 通过在键的 X 事件中传递的修饰符值中分配一个位来提供修饰键。按键可以是多个X事件;X 提供了组合这些事件同时保留修饰符的函数。

X 还为键盘上可能出现的每个键定义了符号。它通过在组合事件的函数中进行特殊处理来提供其他值(例如 Unicode)。

但“元”是一个特例。

X 应用程序没有meta密钥,除非按照惯例。X 没有元键或元修饰符的定义。按照惯例,终端会查找Alt-key 和/或 已知的修饰符之一xmodmap,例如mod2。后来的xkb功能通过提供另一层信息来查找密钥,从而使事情变得复杂(但相对于本讨论没有提供任何改进)Alt

xmodmap考虑到既不了解也不了解有关元xkb的任何具体信息,惯例当然只能带您到目前为止。例如,xterm 是可配置的,但并非所有用户都希望以相同的方式配置元。例如,可能不是预期的元密钥,例如,如果它在资源中使用的话。另一个键可能是元键,但用户(特别是在 bash 中使用转义序列的用户)可能希望在按下 时发送转义字符。但请记住,除非将其配置为修饰符,否则任何情况都不会发生:xterm 本身不会组合事件。AlttranslationAlt

xterm 有几个资源设置(在手册页中有记录):

  • altIsNotMeta和( 2007 年altSendsEscape添加)。
  • eightBitInput2006 年起对应于元模式的原始含义,并且为此定义了一个转义序列,它提供了smmrmm(设置/删除元模式)终端功能。
  • eightBitInput于2003 年进行了修改,通过将解码后的 Unicode 值而不是原始输入字节移位 128 来考虑 UTF-8。
  • metaSendsEscape日期从1999 年开始
  • eightBitInput比 更老metaSendsEscape。自 X11R4 (1989) 以来,它实现了模式(添加第八位)或为密钥添加前缀之间的选择。escape但该功能是在启动时确定的:在初始化期间检查以确定输入是否设置为允许 8 位或仅允许 7 位。此后,它没有改变。

有些人将两者等同起来(第 8 位和转义前缀),将后者称为模式。根据您对此事的看法,eightBitInputxterm 的资源设置是获取可用元密钥的解决方案的一部分。

进一步阅读: