为什么这些prog模式键绑定在emacs-lisp-mode中不起作用?

时间:2013-05-28 21:20:41

标签: debugging emacs elisp

我的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。

P.S。我最近了解了electric-indent-mode,它可能完成了与这些键绑定非常相似的东西。然而,这个谜仍然存在。

1 个答案:

答案 0 :(得分:10)

查看emacs-lisp-mode-maplisp-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,但它的键映射不是从prog-mode-map继承,而是从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继承,因此prog-mode-map中的绑定确实对Emacs Lisp模式没有任何影响。

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

更新: I wrote to the mailing list

更新2: The corresponding bug report

更新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继承,有效地复制错误修复。