我的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
,它可能完成了与这些键绑定非常相似的东西。然而,这个谜仍然存在。
答案 0 :(得分:10)
查看emacs-lisp-mode-map
中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,但它的键映射不是从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
继承,有效地复制错误修复。