4

When I go many levels down into the menus in the menu bar, is there a way to go back up just one level? To illustrate:

  1. Start Emacs

  2. Press F10 to open the menu bar

  3. Press Ctrlf to reach the "Edit" menu.

  4. Press Ctrln repeatedly until the "Search" menu item is highlighted:

    Emacs "Edit" menu with the "Search" item highlighted

  5. Then, press Enter to open the "Search" menu:

    Emacs "Search" menu

The problem: When I reach the "Search" menu, how do I go back up to the "Edit" menu that I came from? Is there a keybinding for this?

Drew
  • 75,699
  • 9
  • 109
  • 225
Flux
  • 583
  • 2
  • 16

2 Answers2

2

Short answer is that there isn’t one.

The long answer is that there is sadly no way to answer this question within Emacs it self. Ordinarily with the focus in a buffer you can type C-h m to get a list of keybindings for the modes active in that buffer, or you can type C-h b to get a list of all key bindings for all modes.

But when a menu is open there is no buffer and no list of active modes. In fact you’re in an entirely different event loop, if I understand the code correctly. (That may not be the case when dealing with the Emacs GUI; I’m just talking about the terminal version here.) If you look for the function tty_menu_activate in term.c, you will find that there are only a handful of actions that you can take while in a menu. You can quit the menu, select a menu item, move to the next or previous menu, or move to the next or previous menu item.

If you dig deeper you will find that there are keymaps that determine which keys result in which actions. tty-menu-navigation-map is the one you want in this case.

It took me a while to figure out how tty_menu_activate actually reads keys, since it ultimately calls the generic read_key_sequence function which is used by everything. read_key_sequence must need a keymap in order to function, otherwise it wouldn’t know which keys are prefix keys and thus wouldn’t know when to stop reading a sequence. Turns out that when it calls current-active-maps to find out what keymap(s) to use, it pass t in for the first argument, which tells it to use the values of the overriding-local-map and overriding-terminal-local-map variables, if they have values. Indeed, just before tty_menu_activate is called, this code is run:

  specbind (Qoverriding_terminal_local_map,
        Fsymbol_value (Qtty_menu_navigation_map));

Which is C code equivalent to

(let ((overriding-terminal-local-map tty-menu-navigation-map))
    …)

It would be a lot clearer if this were moved into tty_menu_activate, just prior to the start of the event loop there.

I agree with you that going back to the previous menu would be handy. If you want to implement it yourself you will need to add a symbol for it, perhaps tty-menu-up or tty-menu-back or similar (the DEFSYMS are at the very end of term.c), change the definition of tty-menu-navigation-map to include some bindings for it, extend the enum mi_result in term.c, change read_menu_input in term.c to return that new enum variant in the appropriate cases, and finally change tty_menu_activate (also in term.c) to keep a history of nested menus so that it knows which one to go back to.

Or you could just tap the left arrow key followed by the right arrow key.

db48x
  • 15,741
  • 1
  • 19
  • 23
1

With vanilla Emacs there's no way that I'm aware of, as @db48x reported.

However, here are 3 libraries that let you do it: La Carte, Key See, and Icicles.

La Carte

Use completion to match anything in any menu-bar menu, anywhere, anytime. Doesn't matter where you are currently - what the current context is. You always have the entire menu-bar forest of menus available to you, and you can always match anywhere - any submenu or any menu item - in any of those menus.

Key See

Use completion to match any key bindings, including menu-bar bindings. Command kc-complete-menu-bar limits candidates to the latter (i.e., not keyboard key bindings).

Completion candidates at any time are at a single menu level. But you can go back up a level by choosing the special candidate ...

Icicles

This gives you everything that Key See gives you, and more.

And it enhances the behavior of La Carte, giving you much more control over exploring the menu forest. Key features in this regard are progressive completion, sorting of candidates, more powerful matching, showing candidate help, and filtering history.

db48x
  • 15,741
  • 1
  • 19
  • 23
Drew
  • 75,699
  • 9
  • 109
  • 225