【问题标题】:Emacs keybinding changes between Emacs 23 and Emacs 24Emacs 23 和 Emacs 24 之间的 Emacs 键绑定更改
【发布时间】:2012-09-11 02:42:28
【问题描述】:

我最近升级到 Emacs24,我的一些自定义键绑定因此而损坏。

根据the fine manual,,可以使 Emacs 停止将功能键与其 ASCII 控制代码混为一谈(例如,可以将 C-mRET 绑定到不同的东西,或者 C-i 和 @987654325 @, 等等)。这一直是我对 Emacs 的一大不满,即如此宝贵的“第一级”键盘快捷键被浪费在了我已经在键盘上有专用键的事情上。在我的情况下,我想将它们绑定到不同的东西,以通过模仿 gedit 来“现代化”键绑定。在 Emacs23 中,这运行得很好:

(global-set-key (kbd "C-i") 'goto-line)
(global-set-key (kbd "C-m") 'comment-or-uncomment-region)
(global-set-key (kbd "C-d") 'kill-whole-line)

;; Fix some stuff broken by the above
(global-set-key [delete] 'delete-char)
(global-set-key (kbd "TAB") 'indent-for-tab-command)
(global-set-key (kbd "RET") 'newline)

然后,我升级到 Emacs24,它坏了,有点。它仍然“有效”,因为C-m 肯定做一件事,RET 做另一件事,但问题是返回键在终端模式或迷你缓冲区中不再正常运行。在这两种情况下,返回键都没有激活我刚刚输入的命令,而是简单地将光标向下移动到下一行,我无法激活我输入到 minibuffer 或终端的命令。

具有讽刺意味的是,Emacs24 对删除的行为进行了很多更改,并且在此过程中他们将 C-dDEL 解耦,因此实际上现在可以安全地将 C-d 绑定到某个东西而无需绑定 DEL回到预期的行为,所以如果我可以为我的返回键实现类似的“它只是工作”行为,而C-m 绑定到其他东西,那就太好了。

因此,我可以设想两种可能的解决方案来解决这个问题。可能看起来像这样:

(global-set-key (kbd "C-m") 'comment-or-uncomment-region)
(global-set-key (kbd "RET") 'do-what-i-expect-the-return-key-to-do-in-any-mode)

或者,这样的东西会更好:

(setq decouple-ascii-control-codes-from-function-keys t)

但我不知道有任何此类变量或函数可以在这种情况下帮助我。

我曾多次尝试使用模式挂钩来恢复终端和迷你缓冲区模式中的正确绑定,但我似乎无法正常工作。救命!

谢谢。

【问题讨论】:

    标签: emacs key-bindings emacs23 emacs24


    【解决方案1】:

    这似乎有效:

    (add-hook 'find-file-hook
              (lambda ()
                (local-set-key (kbd "C-m") 'comment-or-uncomment-region)
                (local-set-key (kbd "<return>") 'newline-and-indent)))
    

    这里的想法是,我们不是在全局范围内修改返回键(这会破坏终端和 minibuffer 缓冲区),而是仅在每个缓冲区的基础上设置这些键绑定,除了我们无条件地为所有缓冲区执行此操作表示磁盘上的文件。

    效率有点低,每次打开文件时都必须运行,但它很好,因为我不必考虑“修复”所有可能的模式,它根本不会破坏终端/迷你缓冲区/首先是等模式。

    【讨论】:

    • 您无需担心效率低下。如果您查看find-file 通常所做的工作量(例如使用M-x find-function RET find-file-noselect RET),您对local-set-key 的两次调用显然可以忽略不计。
    • 它们可能可以忽略不计,但“它已经很慢了,让它变得更糟不会有什么坏处!”是一种马虎的态度。 Stefan 的回答非常好,不费吹灰之力就解决了问题。
    • Stefan 的回答很好,我只是指出您的回答也有可取之处,并已投赞成票。我并没有说它“已经很慢”了,在评估变更如何影响执行路径方面也没有什么草率的地方。
    【解决方案2】:

    在 Emacs 中默认处理这些“姐妹键”的方式是(通过功能键映射)将特殊键(如 tabreturn)重定向到它们的 ASCII 等效项,然后只添加与 ASCII 版本的键绑定。 所以你可以很容易地为非 ASCII 版本添加新的含义,比如

    (global-set-key [return] 'my-new-command)
    

    但在您的情况下,您想要做相反的事情,即让 return 在更改 C-m 时表现得像以前一样。我能想到的最可靠的方法(在它应该与大多数主要/次要模式绑定一起使用的意义上是可靠的)是尽早且无条件地将C-m重新映射到一些新事件,如:

    (define-key input-decode-map [?\C-m] [C-m])
    (define-key input-decode-map [?\C-i] [C-i])
    

    这不会影响returntab 的处理,因为input-decode-mapfunction-key-map 之前应用,即在这些键转换为ASCII 控制键之前。所以你可以这样做:

    (global-set-key [C-m] 'my-new-command)
    (global-set-key [C-i] 'my-newer-command)
    

    一个缺点是,这不仅适用于C-i 的绑定,还适用于C-c C-i 的绑定,现在只能作为C-c TAB 工作(有时会很好,但有时可能不太容易记忆) .

    另一个缺点是,如果有tab 的绑定,那么tab 将无法使用C-i 绑定。但是我们可以通过添加以下内容来解决这两个问题:

    (define-key function-key-map [C-i] [?\C-i])
    (define-key function-key-map [C-m] [?\C-m])
    

    如果没有使用新事件的绑定,这会将新的C-i 事件转回正常的C-i

    【讨论】:

    • 我逐字复制并粘贴了您的解决方案,但它似乎只适用于C-m 而不适用于C-i。例如,C-mRET 成功地执行了不同的操作,但是当我按下 TAB 键时,它执行了我绑定到 C-i 的操作。关于为什么的任何想法?无论如何,我接受了你的回答,只是因为C-m 是我正在努力解决的问题;我已经有 C-iTABglobal-set-key 一起工作。
    • 没关系,我的 .emacs 中似乎有其他东西在干扰。我删除了它,您的解决方案在 emacs24 中逐字运行。谢谢!
    猜你喜欢
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    • 2016-12-15
    相关资源
    最近更新 更多