Josh Tilles
Josh Tilles

Reputation: 1271

Why is it that these prog-mode keybindings aren't working in emacs-lisp-mode?

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

Answers (1)

user355252
user355252

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

Related Questions