1

By default C-x n is a prefix keymap used for narrowing.

I want to bind C-x n to windmove-down.

(global-set-key (kbd "C-x n") 'windmove-down)

This works fine for Text mode. But many major modes seem to overwrite these bindings:

  • Markdown mode:
    • C-x n b → markdown-narrow-to-block
    • C-x n s → markdown-narrow-to-subtree
  • Orgmode:
    • C-x n b → org-narrow-to-block
    • C-x n e → org-narrow-to-element
    • C-x n s → org-narrow-to-subtree

So I would like to know: How can I stop all (major) modes from overwriting my binding?

2

2 Answers 2

4

You should steal the technique used by bind-key*.

Basically, the bindings in minor modes take precedence over major modes, and minor modes in the emulation-mode-map-alists take über precedence. Mastering Emacs has a good outline of keymap lookup order.

Here's a sampling from my config:

(defvar my/keys-keymap (make-keymap)
  "Keymap for my/keys-mode")

(define-minor-mode my/keys-mode
  "Minor mode for my personal keybindings."
  :init-value t
  :global t
  :keymap my/keys-keymap)

;; The keymaps in `emulation-mode-map-alists' take precedence over
;; `minor-mode-map-alist'
(add-to-list 'emulation-mode-map-alists
             `((my/keys-mode . ,my/keys-keymap)))

(define-key my/keys-keymap (kbd "M-o") 'other-window)
2
  • Worked wonderfully and even feels somewhat cleaner then just globaly defining multiple related keybindings one by one. Thank you.
    – Kaligule
    Commented Jun 3, 2021 at 14:29
  • I tried this approach and somehow it never worked for me; I think there's something with use-package and hyperbole's loading process. What worked for me was emacs.stackexchange.com/a/75075/19526.
    – Dan Drake
    Commented Jul 9, 2023 at 14:34
1

Emacs has no mechanism to prevent this other than convention. The convention is that all of the alphabetical keys starting with C-c are reserved for the user. You could change your key binding to C-c n and it wouldn’t be overwritten.

The other alternative is to configure hook functions in your init file so that when a buffer enters a mode that shadows your C-x n binding, your hook function resets your keybinding in the mode’s local keymap. However, this probably means writing a different hook function for every mode.

Not the answer you're looking for? Browse other questions tagged or ask your own question.