0

For a given command, lets say C-c C-k, how to list the bindings of this key for all modes ?

C-h k KEY show bindings only for the current mode. It's the same for invert commands like C-h f and C-h b.

Purpose of this is I wrote a new function, usable in different modes. I want to bind it to a key, but I first want to know if it is already bound.

6
  • What do you mean by "all modes"? – NickD Jul 6 '20 at 13:59
  • I mean C-c C-k is already bind in tex mode and not in lisp mode for example. So There is lot's of different modes in Emacs and I would like the binding for all of these. – Welgriv Jul 6 '20 at 14:11
  • There are sequences reserved for end users, so that you don't need to worry about clashing. gnu.org/software/emacs/manual/html_node/elisp/… – phils Jul 6 '20 at 21:05
  • You're also fairly safe with Super and Hyper modifiers, if you have those. – phils Jul 6 '20 at 21:07
  • I saw this piece of the doc but the bullet explicitly starting with "Don't define C-c letter as a key", so I'm really confused now. What should I do in general when I want to bind some key to a custom function ? – Welgriv Jul 7 '20 at 11:29
2

phils is correct; if you use C-cletter for your personal customizations then you're not supposed to have to worry about conflicts with the key bindings from a mode.

As for actually enumerating all possible keymaps to check if they would define the same shortcut… that's a bit difficult. As far as I know, there's no global list of all keymaps. There's no global list of all variables that are defined, so you can't enumerate all variables and check for keymaps either. In fact, there's no requirement that a keymap has to be stored in a variable at all; it can be created on the fly for transient use. Finally, most keymaps aren't even in memory at all until they are first used. All that Emacs knows at startup is that some symbols are defined but not yet loaded, and what file to load them from.

I wouldn't say that it's completely impossible, however.

With sufficient determination, you could take advantage of the autoloader system to get a list of variables that hold keymaps. Each variable that is to be autoloaded has to be declared as such by calling the autoload function (Use C-h f autoload to see the documentation). You could advise the autoload function and save a list of keymaps to a variable of your choosing. Something like this:

(define-advice autoload (:before (function file &optional docstring interactive type) stash-keymap-names)
  "stashes the names of symbols holding autoloaded keymaps in *my-list-of-keymaps*"
  (when (eq type 'keymap)
    (add-to-list '*my-list-of-keymaps* function)))

However, there is another wrinkle: the autoload declarations are not read in by Emacs on every startup. That would be too slow. Instead, the list of autoload declarations is created during the Emacs build process. This list is then read in once by Emacs (along with a number of other lisp files). The running Emacs then dumps it's own memory out into a new Emacs executable, so that everything created by those lisp files that it read in is automatically available the next time Emacs is run, without having to load any lisp files at all.

So what you need to do is to define this advice very early on in the boostrap process, before it reads the autoload declarations. The variable you're stashing keymap names into will then be baked into the resulting Emacs executable. You can then run the new executable and use the list of symbols to enumerate most of the keymaps that Emacs will ever use.

4
  • Well, honestly it seems very complicated, I thought it might be simpler. However I'm still confuse by the C-c letter of the documentation that starting by "Don't define C-c letter as a key", you seems to tell me the exact opposite. I think I got something wrong... – Welgriv Jul 7 '20 at 11:27
  • 2
    You as a user are allowed to define any keyboard shortcuts you want. However, if you were wanting to contribute something to Emacs to be included with it, then the other developers of Emacs wouldn't let you define any new keyboard shortcuts of the form C-c letter, because those are specifically reserved for end users. As an end user, you now know that any keyboard binding of this type is unlikely to shadow any keyboard shortcut that comes with Emacs. – db48x Jul 7 '20 at 12:31
  • Howw ok! I didn't get that the doc was for developers and not for end users. – Welgriv Jul 7 '20 at 12:43
  • To be fair, all of the developers are also end users, and lots of end users become developers. Overall it's a good thing, but it does make writing the documentation harder. – db48x Jul 7 '20 at 13:06
1

A partial answer, just to say how you can get a list of all variables currently bound to keymaps:

(let ((symbs  ()))
  (mapatoms (lambda (s)
              (when (and (boundp s)  (keymapp (symbol-value s)))
                (push (indirect-variable s) symbs))))
  symbs)
0

I've taken @Drew's answer and blended it with https://stackoverflow.com/a/36994486/324105 to produce this command:

(defun my-describe-all-keymaps ()
  "Describe all keymaps in currently-defined variables."
  (interactive)
  (with-output-to-temp-buffer "*keymaps*"
    (let (symbs seen)
      (mapatoms (lambda (s)
                  (when (and (boundp s) (keymapp (symbol-value s)))
                    (push (indirect-variable s) symbs))))
      (dolist (keymap symbs)
        (unless (memq keymap seen)
          (princ (format "* %s\n\n" keymap))
          (princ (substitute-command-keys (format "\\{%s}" keymap)))
          (princ (format "\f\n%s\n\n" (make-string (min 80 (window-width)) ?-)))
          (push keymap seen))))
    (with-current-buffer standard-output ;; temp buffer
      (setq help-xref-stack-item (list #'my-describe-all-keymaps)))))
2
  • n.b. After following a link, the "back" button behaviour will be somewhat unreliable, as merely following help links might cause libraries to be autoloaded, potentially bringing in new keymaps, meaning the buffer you'll go back to might have different content to the one you left, causing the remembered position to be offset from where you'd want it to be. – phils Jul 8 '20 at 0:33
  • Neat; I didn't know about mapatoms. This looks more convenient than my solution. – db48x Jul 8 '20 at 9:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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