简体   繁体   中英

Key bindings are overwritten in emacs

I have my own user defined key-bindings as described here: Globally override key binding in Emacs

Whenever I load a new major mode, say OrgMode, I have some of my bindings over-written to fit my needs in that specific mode. But then when I load another major mode, which have its own over-writes, they stay put even if I'm not in a buffer with that major mode anymore.

For example

(define-key custom-keys-mode-map (kbd "C-p") 'some-cool-function)
(add-hook 'org-mode-hook
    (lambda ()
    (define-key custom-keys-mode-map (kbd "C-p") 'org-cool-function )))
(add-hook 'sunrise-mode-hook
    (lambda ()
    (define-key custom-keys-mode-map (kbd "C-p") 'sunrise-cool-function )))

At first I use Cp to execute my cool, default, function. After I load Org-Mode I use Cp to execute "org-cool-function", and when I load Sunrise-Commander, Cp executes "sunrise-cool-function".

But then when I go back to an Org-Mode file, Cp still tries to execute "sunrise-cool-function" instead of "org-cool-function".

Hope I'm clear:)

The behavior you see is what is expected from the code. It goes as follows:

  • you launch emacs and some-cool-function gets assigned
  • then whenever you open a new org file (and not just switch buffer to it) org-cool-function gets assigned
  • whenever you launch sunrise-commander sunrise-cool-function gets assigned

Your problem comes from trying to set a global property from a local event.

You should use the org-mode-map instead of custom-keys-mode-map to put your Cp keybinding. This will set it once and for all for every buffer with org content:

(define-key custom-keys-mode-map (kbd "C-p") 'some-cool-function)
(eval-after-load "org"
  '(define-key org-mode-map (kbd "C-p") 'org-cool-function))

Minor mode maps supersede major mode maps which supersede the global map.

So a few options are:

  1. Do not include these bindings in your custom minor mode map at all. Make your preferred binding a plain global binding, and let the major modes over-ride it as required.

  2. Create additional minor modes to take precedence over your existing minor mode, and enable them in the corresponding major modes. Each minor mode's position in minor-mode-map-alist determines precedence when looking up key bindings, so you need these additional modes to be defined after your current mode is defined (meaning that they will appear earlier in the alist), and of course keep them in that order if updating that list dynamically .

  3. Leave everything the way it is, but bind these keys to custom functions which check the major mode and act accordingly. You may or may not need to take care of passing on prefix arguments if you take this approach.

I've read a couple more threads which led me to believe there is another way, which I'm currently using:.

Currently I'm using this:

;;; Disable Custom keys for specific major modes.
(define-global-minor-mode my-custom-keys-mode custom-keys-mode
  (lambda ()
    (when (not (memq major-mode (list 'sr-mode)))
      (custom-keys-mode))))
(my-custom-keys-mode 1)

which pretty much suits my needs at the moment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM