M-S-<left> 未按预期处理

M-S-<left> not processed as expected

当我像这样在终端中启动一个新的 emacs 时

emacs -nw -Q

我可以尝试通过键入 C-h k 来检查某个键盘快捷键绑定的是什么。当我在启动 Emacs 后立即对 *scratch* 缓冲区中的快捷方式 M-S- 执行此操作时,我得到:

<M-left> runs the command left-word (found in global-map), which is an interactive compiled Lisp function in ‘bindings.el’.

It is bound to <C-left>, <M-left>.

[...]

注意在识别的键序列中缺少 "Shift" 修饰符。

现在,第一直觉是终端(在我的例子中是 gnome-terminal)没有产生正确的转义序列,但它确实产生了:输入 CTRL-V ALT-SHIFT-left 在终端中(即不在 Emacs 中)产生

^[[1;4D

并在 Emacs 中键入 C-q C-S- 将相同的内容插入当前缓冲区。 (注意^[是单个字符,即ASCII 27("Escape")。)

检查 input-decode-map 显示以下值(为简洁起见,省略了一些部分(标记为 ...)):

(keymap
 (27 keymap ... )
 keymap
 (keymap
  (27 keymap
      ...
      (91 keymap
          ...
          (51 keymap
              ...
              (59 keymap
                  (51 keymap
                      ...
                      (68 .
                          [M-left])
                  (52 keymap
              ...
                      (68 .
                          [M-S-left])
                      ...)
                  ...)
              ...)
          ...))))

使用以下代码验证两个键序列可得到预期结果:

(mapc '(lambda (c) (insert (format "%c" c))) '(27 91 49 59 51 68)) ; ^[[1;3D
(mapc '(lambda (c) (insert (format "%c" c))) '(27 91 49 59 52 68)) ; ^[[1;4D

但是,我不明白为什么这些序列嵌入到二级内部 (keymap ...) 列表中?!

越来越奇怪了。

回到 *scratch*,当我输入

M-x local-set-key

然后 M-S-,它被正确识别,正如迷你缓冲区中的下一个提示所示:

Set key <M-S-left> locally to command:

如果我继续并提供一个随机函数,比如 beginning-of-line,随后调用 C-h k,然后是 M-S- 然后确实给出:

<M-S-left> runs the command beginning-of-line (found in lisp-interaction-mode-map), which is an interactive built-in function in ‘C source code’.

It is bound to <M-S-left>.

[...]

本地设置 M-S-nil 将恢复 C-h k 报告 M-S-<左><M-left>.

这是怎么回事?这是一个配置问题,还是预期的行为,或者是否涉及透明地添加另一层重新映射的其他一些键映射?

这是一项功能。

M-x elisp-index-search RET shift-translation 说:

If an input character is upper-case (or has the shift modifier) and has no key binding, but its lower-case equivalent has one, then ‘read-key-sequence’ converts the character to lower case. Note that ‘lookup-key’ does not perform case conversion in this way.

When reading input results in such a “shift-translation”, Emacs sets the variable ‘this-command-keys-shift-translated’ to a non-‘nil’ value. Lisp programs can examine this variable if they need to modify their behavior when invoked by shift-translated keys. For example, the function ‘handle-shift-selection’ examines the value of this variable to determine how to activate or deactivate the region (*note handle-shift-selection: The Mark.).