7

i am using a mode, but am not used to its key-bindings: some of them conflict to the emacs global ones. so, i want to add a prefix key-binding to all its existing keybindings.

for example, if my-mode defines key-binding M-] for my-mode-shot, i am looking for some ways as following:

(define-prefix-for-mode 'my-mode (kbd "C-c m"))

then the key-binding for my-mode-shot now is C-c m M-].

how should one add a prefix key-binding to all available key-bindings of a specific mode?

象嘉道
  • 191
  • 5
  • 1
    It can depend on the kind of mode. Can you give details? – Stefan May 11 '16 at 14:57
  • @Stefan i am looking for a general solution, not a mode-specific one. – 象嘉道 May 12 '16 at 15:19
  • A solution that works reliably for all modes is probably impossible. You can probably cook up a solution, using the code I provided, which will work for most major modes, tho. – Stefan May 12 '16 at 15:22

3 Answers3

4

One way to move -mode's keybindings could be with something like

(let ((origmap <foo>-mode-map)
      (newmap (make-sparse-keymap)))
  (define-key newmap <prefix> origmap)
  (setq <foo>-mode-map newmap))  

But this code will fail if run before foo-mode is run. And it will have no effect if run after the mode is entered. So you'll probably have to do it within `(with-eval-after-load '-mode ...).

Also, if it's a minor mode, the above code won't have any effect either, because you additionally have to do something like (within the above let):

(setcdr (assq '<foo>-mode minor-mode-map-alist) newmap)
nispio
  • 8,175
  • 2
  • 35
  • 73
Stefan
  • 26,154
  • 3
  • 46
  • 84
2
  1. Define a prefix key for the mode's keymap.
  2. Undefine the other keys that bother you, from that keymap.

Suppose that mode foo-mode binds key C-x o to foo-it, and you don't like that.

(define-key foo-mode-map (kbd "C-x o") nil)

And suppose you want foo-mode-map on prefix key <f9>:

(define-prefix-command 'foo-mode-map)
(define-key global-map (kbd "<f9>") 'foo-mode-map)
Drew
  • 75,699
  • 9
  • 109
  • 225
  • This will also cause that `foo-it` will not be available via ` C-x o`, which might be self-defeating if the goal is to move the keybindings out of the way while remaining accessible through the prefix key. – nispio May 11 '16 at 18:11
1

You can modify the mode's keymap directly to move all the bindings under your chosen prefix:

(setcdr my-mode-map
  `(keymap (?\C-c keymap (?m keymap . ,(cdr my-mode-map)))))