【问题标题】:M-S-<left> not processed as expectedM-S-<left> 未按预期处理
【发布时间】:2019-02-08 07:17:12
【问题描述】:

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

emacs -nw -Q

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

运行命令 left-word(在 global-map 中找到),它是 在“bindings.el”中交互式编译的 Lisp 函数。

绑定到

[...]

请注意识别的键序列中缺少“Shift”修饰符。

现在,第一个直觉是终端(在我的例子中是 gnome-terminal)没有产生正确的转义序列,但它确实产生了:输入 CTRL-V ALT-SHIFT-left in终端(即不在 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-,它被正确识别,正如 minibuffer 中的下一个提示所示:

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

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

运行命令开头的行(在 lisp-interaction-mode-map),这是一个交互式内置函数 在“C 源代码”中。

绑定到

[...]

M-S- 本地设置为 nil 将恢复 C-h k 报告 M-S- 的初始行为作为&lt;M-left&gt;

这里发生了什么?这是配置问题,还是预期行为,还是涉及透明添加另一层重映射的其他一些键映射?

【问题讨论】:

  • 这是哪个版本的 Emacs?对我来说,Emacs 26.1 报告 &lt;M-left&gt; (translated from &lt;M-S-left&gt;) runs the command left-word。您可能会看到相同的行为,而没有被明确告知这是一个翻译序列。
  • GNU Emacs 25.2.2
  • 仅供参考,我刚刚在 25.3 中进行了测试(IIRC 只是 25.2 之上的一个安全补丁),我也在那里看到了“翻译自”文本。我觉得它已经存在了很长时间(可能自从引入了移位翻译功能以来),所以我仍然对为什么您自己没有看到它感到有些困惑。
  • 我似乎确实记得自己在过去看到过“翻译自”消息(旧 Emacs 版本)。这就是我引用我得到的输出的前几行的原因,因为在我的版本中显然没有提到它。

标签: emacs


【解决方案1】:

这是一个功能。

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

如果输入字符是大写的(或有移位修饰符)并且 没有键绑定,但它的小写等效项有一个,那么 ‘read-key-sequence’ 将字符转换为小写。注意 ‘lookup-key’不以这种方式进行大小写转换。

当读取输入导致这种“移位翻译”时,Emacs 设置 变量“this-command-keys-shift-translated”为非“nil”值。 如果 Lisp 程序需要修改它们的 由移位转换键调用时的行为。例如, 函数‘handle-shift-selection’检查这个变量的值以 确定如何激活或停用该区域(*注 handle-shift-selection:标记。)。

【讨论】:

  • 非常感谢。我猜,您在较新的 Emacs 中收到的 (translated from &lt;M-S-left&gt;) 消息也会为我解决问题。想起来,这是一种愚蠢的“功能”——除非我碰巧按了 Shift,否则我没有输入键盘快捷键的“小写”版本可能是有原因的。这也不一致:在我的键盘上,+S-= 相同,但是当我 (global-set-key "+" nil) 时,我在迷你缓冲区中得到“+ 未定义”,而不是插入了 =
  • 我不确定这是否完全正确,但您可以将其解释为“shift-translation 会影响字母 A-Z 以及还没有 shift 行为的键”。
  • 如果您还没有使用过,另请参阅 shift-select-mode -- 我不使用它,但我认为这就是为什么首先存在此功能的原因。
  • 写你的最后一条评论,@phils:不。我很确定这种行为是旧的,shift-select-mode 是相对较新的。是的,它最初是关于字母的 - 默认情况下,通过使 Shift 键与字母键绑定无关,这被认为是一种方便。
猜你喜欢
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
  • 2016-09-16
  • 1970-01-01
  • 1970-01-01
  • 2019-12-08
  • 1970-01-01
  • 2023-03-17
相关资源
最近更新 更多