bash 的元键是什么?

bash 的元键是什么?

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

让我换一种说法。例如,bash 手册页显示,函数 yank-nth-arg 已绑定,M-C-y并且当我按 时它会起作用Esc-Control-y。但我觉得这有点麻烦。那么我怎样才能让 bash 接受另一个键作为它的所有默认绑定Meta(如)?Menu

答案1

Meta从键盘按键到修饰符(例如和 )的映射Control由 X 服务器(即 GUI 的低级部分)处理。可以通过旧式来操纵此映射xmodmap命令或新式XKB界面,或通过在幕后使用其中之一的 GUI 配置工具。

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

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

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

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

答案2

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

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

答案3

巴什的元键最初是这样定义的(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.

这恰好是它的解释方式恩诅咒xterm。 A很少为使此功能成为可选而提供的终端(这方面并不普遍。您将遇到的大多数终端都使用硬编码行为(并且不是很有趣)。术语信息手册页记录了这些终端功能:

   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)

并解释了该功能:

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

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

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

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

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

但“元”是一个特例。

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

惯例当然只能带你到目前为止,因为你既不知道xmodmap也不xkb知道任何具体的事情。例如,xterm 是可配置的,但并非所有用户都想要配置以同样的方式。例如,Alt可能不是预期的元密钥,例如,如果它在translation资源中使用的话。另一个键可能是元键,但用户(特别是在 bash 中使用转义序列的用户)可能希望在按下 时发送转义字符Alt。但请记住,除非将其配置为修饰语这些都不会发生:xterm 本身不会组合事件。

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

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

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

进一步阅读:

相关内容