1

I have defined a keymap my-custom-key-map with some commands. This keymap lives in memory. There is no (prefix) key to activate this keymap.

How to activate this keymap from lisp code?

I don't want to bind this keymap to a prefix key. I want to "invoke" it from lisp code.

Example I have a command which does things. And after it has done it, I want my keymap activated. So that when I type a key from the keymap, the associated command is invoked. Then the keymap should deactivate again and not be accessible anymore. Until my command activates it again for just one usage.

Another way to ask the question: I want to do what a prefix key does when it is bound to a keymap. It activates the keymap for one key stroke. This is what I want to do.

Another one: I want to do what a leader key does. It activates? starts? triggers? invokes? its keymap.

Another one: Given, I have defined (global-set-key (kbd "X H") 'help). What does emacs invoke when I press X?

5
  • See Controlling the Active Keymaps in the Emacs Lisp Reference manual. Be prepared for some studying and some experimentation.
    – NickD
    Commented Mar 27, 2023 at 17:11
  • What does "invoking a key map" mean? A key map is just a table. I assumed you wanted to make a key map active in my previous comment, but on thinking about it some more, I don't understand what you are trying to do.
    – NickD
    Commented Mar 27, 2023 at 17:25
  • I have put more context into my question.
    – Witek
    Commented Mar 27, 2023 at 18:20
  • "What does emacs invoke when I press X?" Assuming that this binding is the one that Emacs comes up with after it goes through all the relevant keymaps, after you press X, Emacs does nothing: it waits for you to press another key until it gets a complete key sequence according to the current set of active key maps.
    – NickD
    Commented Mar 27, 2023 at 18:47
  • See function read-key-sequence in the C source of Emacs in the file src/keyboard.c. See also Command Loop Overview and Key sequence input.
    – NickD
    Commented Mar 27, 2023 at 18:47

3 Answers 3

2
(set-transient-map my-custom-key-map)

If you have which-key add also want the visual hints:

(set-transient-map my-custom-key-map)
(which-key-show-keymap 'my-custom-key-map)

C-h f set-transient-map says:

Set MAP as a temporary keymap taking precedence over other keymaps. Normally, MAP is used only once, to look up the very next key. However, if the optional argument KEEP-PRED is t, MAP stays active if a key from MAP is used. KEEP-PRED can also be a function of no arguments: it is called from `pre-command-hook' and if it returns non-nil, then MAP stays active.

3
  • Good one. I didn't know about it.
    – NickD
    Commented Mar 27, 2023 at 18:53
  • One potentially frustrating detail is that activation through set-transient-keymap isn't equivalent to an activation through a prefix: if you don't have a bound in a map and then you bind that map as a prefix (let's say C-SPC), then C-SPC a will report the error C-SPC a is undefined. But if you set it as a transient map and then hit a, it will fall through to the underlying active keymaps. For details on the caveats, why it is, and ideas on how to detect or avoid it, see my answer about limiting read-key-sequence to just one keymap
    – mtraceur
    Commented Feb 15 at 22:51
  • We can make the transient keymap behave the same as a prefix-accessed keymap by composing the keymap we actually want with a keymap in which all keys are defined to the undefined special function. (defconst all-undefined-keymap (make-sparse-keymap)), (define-key all-undefined-keymap [t] 'undefined), and then finally (set-transient-map (make-composed-keymap my-map all-undefined-keymap)).
    – mtraceur
    Commented Feb 17 at 4:10
0

Would this be in the same ballpark. Invoke a key map within a lisp code:

(call-interactively
 (lookup-key my-custom-key-map (read-key-sequence nil)))

There is also a hydra package that runs transient key maps. A hydra is like a key map, I suppose, and, I think, it can be invoked within lisp code.

-1

You can use the function which-key-show-keymap for that. Interactively via M-x, or programmatically (e.g. via M-:) as follows

(which-key-show-keymap 'my-custom-key-map)
5
  • It seams this does only show the keymap. But when I hit a key from it, it does not execute the command. I want to "use" the keymap. Not only show it. Someone has changed the title of my question and redefined it :-(
    – Witek
    Commented Mar 27, 2023 at 16:31
  • 1
    If you disagree with an edit, you can see the change history by clicking on the edited NN mins ago link and rollback the questionable edit, by hitting the Rollback link.
    – NickD
    Commented Mar 27, 2023 at 16:45
  • Ah okay, that was not clear from your original question (and actually, to me, also not really from your updated question). Indeed, I edited the title to what I assumed that you really meant. I guess, by using just which-key it is not really possible to 'replace' the root map with your custom key map (not sure). However, I guess you could make it a minor-mode keymap (e.g. name my-custom-minor-mode). Then you could activate the minor mode while 'programmatically' invoking which-key. Commented Mar 27, 2023 at 17:14
  • I am looking for a solution which also works without whichkey.
    – Witek
    Commented Mar 27, 2023 at 18:16
  • Problem is, I dont' know the name for the action I need. Say, I have defined (global-set-key (kbd "X H") 'help). What does emacs invoke when I press X?
    – Witek
    Commented Mar 27, 2023 at 18:32

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.