Reputation: 1271
I have a couple lines in my Emacs setup:
;; swap defaults
(define-key prog-mode-map (kbd "RET") 'newline-and-indent)
(define-key prog-mode-map (kbd "C-j") 'newline)
This works as expected in the couple of other programming modes that I tried. But in the Emacs Lisp mode, RET was still bound to newline
and C-j was still bound to newline-and-indent
. I still observed this confusing behavior even after moving the keybinding code to the very beginning of my Emacs initialization. If I create separate keybinding statements for Emacs Lisp's mode, I don't have any problems.
;; 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)
Why is this? If it matters, I'm using Emacs 24.3 on OS X 10.8.3.
P.S. I recently learned about electric-indent-mode
, which probably accomplishes something very similar to these keybindings. However, the mystery still stands.
Upvotes: 4
Views: 877
Reputation:
Look at the definition of emacs-lisp-mode-map
in 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))
The key is the set-keymap-parent
call. Though Emacs Lisp Mode inherits from Prog Mode, its keymap does not inherit from prog-mode-map
, but from another keymap defined in 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.")
This keymap also does not inherit from prog-mode-map
, so bindings in prog-mode-map
do indeed not have any effect in Emacs Lisp Mode.
This is arguably a bug in Emacs.
Update: I wrote to the mailing list.
Update 2: The corresponding bug report
Update 3: The bug has been fixed. In a current snapshot build your key bindings should work as expected. As a work around for earlier builds of Emacs you can use the following snippet in your init.el
:
(unless (keymap-parent lisp-mode-shared-map)
(set-keymap-parent lisp-mode-shared-map prog-mode-map))
Now lisp-mode-shared-map
will inherit from prog-mode-map
, effectively replicating the bug fix.
Upvotes: 10