4

我的 Emacs 设置中有几行:

;; swap defaults
(define-key prog-mode-map (kbd "RET") 'newline-and-indent)
(define-key prog-mode-map (kbd "C-j") 'newline)

这在我尝试的其他几种编程模式中按预期工作。但是在 Emacs Lisp 模式下,RET仍然绑定到newline并且C-j仍然绑定到newline-and-indent. 即使将键绑定代码移至 Emacs 初始化的最开始,我仍然观察到这种令人困惑的行为。如果我为 Emacs Lisp 的模式创建单独的键绑定语句,我没有任何问题。

;; swap defaults for most programming modes
(define-key prog-mode-map (kbd "RET") 'newline-and-indent)
(define-key prog-mode-map (kbd "C-j") 'newline)

;; swap defaults in Emacs Lisp mode too
(define-key emacs-lisp-mode-map (kbd "RET") 'newline-and-indent)
(define-key emacs-lisp-mode-map (kbd "C-j") 'newline)

为什么是这样?如果重要的话,我在 OS X 10.8.3 上使用 Emacs 24.3。

PS 我最近了解到electric-indent-mode,它可能完成与这些键绑定非常相似的事情。然而,谜团仍然存在。

4

1 回答 1

11

查看emacs-lisp-mode-mapin的定义lisp-modes.el

(defvar emacs-lisp-mode-map
  (let ((map (make-sparse-keymap "Emacs-Lisp"))
        (menu-map (make-sparse-keymap "Emacs-Lisp"))
        (lint-map (make-sparse-keymap))
        (prof-map (make-sparse-keymap))
        (tracing-map (make-sparse-keymap)))
    (set-keymap-parent map lisp-mode-shared-map)
    …
    map))

关键是set-keymap-parent通话。虽然 Emacs Lisp Mode 继承自 Prog Mode,但它的 keymap 不是继承自prog-mode-map,而是继承自另一个定义在 中的 keymap lisp-modes.el

(defvar lisp-mode-shared-map
  (let ((map (make-sparse-keymap)))
    (define-key map "\e\C-q" 'indent-sexp)
    (define-key map "\177" 'backward-delete-char-untabify)
    map)
  "Keymap for commands shared by all sorts of Lisp modes.")

这个键映射也不继承自prog-mode-map,因此在 Emacs Lisp 模式中的绑定prog-mode-map确实没有任何影响。

这可以说是 Emacs 中的一个错误。

更新: 我写信给邮件列表

更新 2: 相应的错误报告

更新 3:该错误已修复。在当前的快照构建中,您的键绑定应该按预期工作。作为 Emacs 早期版本的解决方法,您可以在您的 中使用以下代码段init.el

(unless (keymap-parent lisp-mode-shared-map)
  (set-keymap-parent lisp-mode-shared-map prog-mode-map))

现在lisp-mode-shared-map将继承自prog-mode-map,有效地复制错误修复。

于 2013-05-29T08:39:06.557 回答