;;
;; ~ropmur-bicbus
;;

Override global-set-key in Emacs

emacs

I like using org-secretary, but there's one thing that I dislike about it.

Problem

org-secretary calls (global-set-key) when it loads. I don't like this because:

  1. I'd prefer to use different bindings for its functionality.

  2. (global-set-key) binds keys in every mode, but these bindings are only useful in org-mode.

Point 1 is easy to solve, but how do I remove the global bindings?

The Naive Solution

The simplest solution would be to call (global-unset-key) for each key that org-secretary binds, like this:

(mapc 'global-unset-key
      '("\C-cW" "\C-cd" "\C-cD" "\C-cj"))

The General Solution

That was a simple solution, but it's very specialized. Is there a general solution that I can apply for any package that binds keys globally?

This seems like a perfect excuse for a macro. A macro can wrap any code that calls (global-set-key), preventing it from binding any keys in the first place!

(defmacro rb/with-global-bindings (&rest forms)
  "Execute FORMS with global-set-key disabled."
  `(let ((dummy ,(lambda (key command) command))
         (res))
     (advice-add 'global-set-key :override dummy)
     (unwind-protect
         (setq res (prog1 ,(macroexp-progn forms)))
       (advice-remove 'global-set-key dummy))
     res))

Now I can load org-secretary and keep my global keymap clean!

(rb/with-global-bindings
 (add-to-list 'org-modules 'org-secretary 't)
 (org-load-modules-maybe 't))