views:

195

answers:

2

Considering a keystroke in Emacs, e.g. C-x C-s. I can figure out which function it invokes by typing C-h c keystroke, but how can I find where this keybinding was defined?

(Maybe the right answer is that it cannot be decided, because the keymaps don't store this kind of information.)

+1  A: 

Just do M-x find-function

From Emacs doc:

(find-function function)

Find the definition of the function near point.

Finds the source file containing the definition of the function near point (selected by `function-called-at-point') in a buffer and places point before the definition. Set mark before moving, if the buffer already existed.

Nuno Furtado
That's not what I'm looking for. It tells me where a *function* was defined not a *keybinding*.
Török Gábor
I dont think you can find that out.
Nuno Furtado
+3  A: 

The information as to where keybindings are associated with functions is not kept by Emacs. In fact, the answer is usually undefined.

Many times key bindings are set up as a side-effect of a minor mode, or through mode-hooks. The key binding for minor modes is often stored in some variable like comint-mode-map. This keymap is enabled by setting the mode-variable comint-mode. However, that mode map is a global variable and anyone, anywhere can add key bindings to it. So, doing what you want is essentially tracking who set a variable with a particular value. Similarly for key bindings that are just set locally through mode hooks (using local-set-key). Plus you can even set up key bindings through file variables. All of this is just to say that the key bindings in Emacs are ephemeral.

About the best you can do is find the function associated with the key, and look in that file (or any related files if the mode is split into multiple files).

Key binding lookup in emacs is fairly involved due to the myriad of ways you can set/associate key strokes (globally, major mode, minor modes, overriding minor modes, local to buffers, text properties, etc.). For a quick overview, check out this documentation.

You can write a function like this to look in the minor modes to see where a keybinding might be set, but of course my first test showed the keybinding wasn't defined there. But perhaps the code will be instructive.

(defun guess-where-keybinding-is-defined (key)
  "try to guess where a key binding might be defined"
  (interactive (list (read-key-sequence "Describe key: ")))
  (let ((bindings (minor-mode-key-binding key))
        found)
    (while (and bindings (not found))
      (if (setq found (caar bindings))
          (find-function (cdar bindings)))
      (setq bindings (cdr bindings)))))

Is there a specific problem you're trying to solve (other than this question)?

Trey Jackson
Thanks for your detailed answer. The question came to my mind yesterday when I was trying to figure out that was a specific keybinding defined in the core modes or by an external package.
Török Gábor