Is there any hook that runs every time a keyboard binding is created/added?

Here's my problem:

I use dvorak and also another layout(some exotic utf8 script) both at system level. And I've got used to dvorak layout(without input-change) for my keyboard bindings. But when I change to the utf8 layout(at system), I've to change back to dvorak every single time I want to do something using shortcuts.

One method I thought was to add new bindings by mapping existing ascii keys to these utf8 chars(on dvorak layout) everytime a keyboard binding is made. Using a list of all bindings doesn't look like a good idea, mostly because it's too much work.

  • Are you saying you want Emacs to always act as if dvorak is in use, even when the other layout is actually in use? Is there any overlap between the codes produced by the two layouts? If not, you could define translation mappings for all the utf8 codes so that Emacs sees them as the codes which dvorak would have sent, and then you don't need to care about which functions are bound. (Even if there is some overlap, that approach might still be useful.)
    – phils
    Jul 16, 2017 at 6:31
  • yes, i'd thought of doing the same initially, but then i also write in the buffer in that exotic script. so i thought mapping every character won't work. so to map the keycombos, i'd to figure some way to access bindings at the startup cuz i only needed basic editing/browsing. i've yet to try Tobias's solution.
    – aksci
    Jul 17, 2017 at 23:06

1 Answer 1


I am not aware of any hook before/after new key-bindings but you can add advices to define-key. define-key is the low-level function called by other functions like global-set-key, local-set-key, or substitute-key-definition-key.

In your case a :filter-args advice seems to be the most appropriate one.

An example code that swaps x and z in newly defined key-sequences:

(defun swap-x-z (arg-list)
  "Swap keys x and z."
  (let ((key (nth 1 arg-list)))
    (cl-loop for stroke being the elements of-ref key
         if (eq stroke ?x) do (setf stroke ?z)
         else if (eq stroke ?z) do (setf stroke ?x))
    (setf (nth 1 arg-list) key))

(advice-add #'define-key :filter-args #'swap-x-z)

;; Example:
(local-set-key (kbd "C-c x") (lambda () (interactive) (insert "C-c x")))

;; After running above code pressing C-c z gives:
C-c x

Note, that I am not so sure that swapping keys for define-key is such a good idea. E.g., you have to deal with the key sequences that are already defined before your code runs separately.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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