The documentation in the release of GNU Emacs 29.0.50 states that global-set-key is a legacy function; instructing people that the recommended function to use is keymap-global-set.

What would be the replacement to

(global-set-key (kbd "C-;") (kbd "C-x C-;"))

1 Answer 1

(keymap-global-set "C-;" "C-x C-;")

Caveat: I know nothing about keymap-global-set. I just tried that in an Emacs 29 pretest build, and it seems to set C-; to the command that's bound to C-x C-;.

The doc string of keymap-global-set doesn't say clearly that argument COMMAND can be a key description (what kbd returns) of a key sequence bound to some command. Maybe it should?

In fact, I think COMMAND is not clear in the doc of keymap-global-set and its siblings. Clearly it's not the same as the COMMAND arg of global-set-key, define-key, etc. For those functions, a sexp such as (kbd "C-x C-;") is what's meant, and not a string such as "C-x C-;". The latter doesn't work for those "legacy" binding functions -- kbd is needed, to distinguish the arg as a "command"/"binding".

What's a "command", as argument to the "legacy" binding functions and their purported replacements?

A sexp such as (kbd "C-x C-;") can be used with command-execute: (command-execute (kbd "C-x C-;")). A string such as (kbd "C-x C-;") cannot. And the Elisp manual makes clear that command means this:


An object which can be invoked via the command-execute primitive, usually due to the user typing in a key sequence “bound” to that command. *Note Interactive Call::. A command is usually a function; if the function is written in Lisp, it is made into a command by an ‘interactive’ form in the function definition (*note Defining Commands::). Commands that are functions can also be called from Lisp expressions, just like other functions.

(On the other hand, function commandp returns t for any string, interpreting it as a keyboard macro. That's not what's involved for argument COMMAND in "legacy" binding functions such as define-key.)

It seems clear that in "legacy" key bindings, argument COMMAND or BINDING is a command in the sense of "An object which can be invoked via the command-execute primitive".

Apparently that's not what such an argument means for the new-fangled replacement functions - you can't use "C-x C-;" with command-execute. And I find nowhere any description of what those functions require as their COMMAND argument.

FWIW, it seems to me that those who introduced keymap-set etc. (and even expect those new functions, which essentially just add the syntax sugar of letting/making you not use kbd, to replace the longstanding and newly baptized as "legacy" functions) did a not-quite-fully-baked job of adding their doc and updating the existing doc. I could be wrong, but (so far) it looks that way to me. On the other hand, I have only a pretest version of Emacs 29, and 29 is not yet released. I'm hoping the doc will be clear when it's released.

  • Yes, converting my configuration from the newly legacy define-key&co to keymap-set, etc. turned into quite a project. It is not just removal of kbd, the allowed syntax in the definition of keys is different. E.g. things like \C, [tab], [remap] no longer work and need to be updated. Sep 30, 2023 at 18:51
  • 2
    FWIW, there's no obligation to convert to using the keymap-* functions.
    – Drew
    Oct 1, 2023 at 1:33

Your Answer

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

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