jennykwan
jennykwan

Reputation: 2701

Emacs: move keybindings for an entire minor mode

I've been yak shaving this for 2 hours, and need to move on, but I'll throw this out to the Internet to see if anything comes up.

I'm loading midje-mode into clojure-mode - midje-mode is a minor mode. The keymap clobbers projectile-mode, which, quite frankly, is infinitely more useful and more commonly used (for me).

midje-mode defines everything under C-c, though with no follow-up chords (Why? It's a damned minor mode!). So I want to move everything to C-c C-m or something similar.

I've tried everything. Nothing sticks. I've hooked into the minor mode startup to unmap and map all entries in the keymap. I did the same hooking into the major mode (clojure-mode). The old bindings don't consistently leave and the new bindings never take place.

I tried following: http://emacsredux.com/blog/2013/09/25/removing-key-bindings-from-minor-mode-keymaps/ No dice. The (define-key 'map (kbd "<foo>") (kbd "<bar>")) doesn't work, and quite frankly, if it ever does, it's nowhere in the GNU docs for Emacs, so I don't know WTH the author is talking about.

I'm just going to remove midje-mode and move on, but it would be nice to know.

Upvotes: 1

Views: 130

Answers (1)

phils
phils

Reputation: 73246

The following will do what you've asked for:

;; Move the `midje-mode-map' prefix from "C-c" to "C-c ."
(with-eval-after-load "midje-mode"
  (let ((prefix-map (lookup-key midje-mode-map (kbd "C-c"))))
    (define-key midje-mode-map (kbd "C-c") nil)
    (define-key midje-mode-map (kbd "C-c .") prefix-map)))

That said, I feel that some of the other suggestions mentioned already should have had an effect, so the fact that you've said that none of them did anything makes me think there's something amiss with how you're trying to apply them, or that there were errors that you didn't notice.

Note that you can't make your desired changes to midje-mode-map before its library has been loaded (because otherwise the keymap doesn't exist); but midje-mode-hook can't run before that library is loaded (so that approach definitely should have been effective); and requireing the library before making the changes also ensures that it's loaded (so that ought to have worked as well).

The eval-after-load approach is generally preferable in these cases, however, as you only want this code to run once, and you don't have to load the library in advance.

Upvotes: 1

Related Questions