2

How do I make the entry in the mode-line popup a minor mode menu when clicked?

For reference see this discussion https://github.com/flycheck/flycheck/issues/365#issuecomment-38386558

Nordlöw
  • 11,838
  • 10
  • 52
  • 99
  • Just a more general remark to be aware of: pop-up windows are frowned upon my many Emacs users. Case in point: https://sites.google.com/site/steveyegge2/effective-emacs#TOC-Dialog-Boxes:-The-Root-of-All-Evil – Thomas Mar 24 '14 at 11:20
  • @Thomas Er, we are talking about **menus**, not windows. –  Mar 24 '14 at 11:49
  • @lunaryorn To me, a menu is a pop-up window, but even if you disagree, I think a similar logic still applies (Section 7 in the link I posted elaborates a bit about menus). Note though that I didn't claim this to be an issue for *all* Emacs users, so your mileage may vary. – Thomas Mar 24 '14 at 14:54
  • 1
    @Thomas Indeed, I disagree. These things have different names in UX design for a reason. And neither section of this article covers popup menus: Item 6 is about *modal* dialog boxes, but popup menus are not modal, and Item 7 is quite obviously about the global menu bar, but we are talking about a minor-mode specific context menu. –  Mar 24 '14 at 15:28
  • @Thomas Besides, my mileage varies indeed. A *good* menu with a few hand-selected important is a lot more discoverable than `M-x`, which just throws you at all existing commands. I can cope with `M-x`, but many new users may not. And in either case, I'm writing a minor mode which is supposed to be a good citizen to Emacs, and that includes providing good menus. I'm not so arrogant as to tell others how they are supposed to use Emacs, or attempt to impose my personal workflow onto their use of Emacs. –  Mar 24 '14 at 15:32

2 Answers2

1

It seems that the menu displayed on clicking the mode-line entry for a mode is the same menu that is displayed when one clicks on the mode's entry in the menu-bar, provided that the mode defines a top level menu entry. The simplest way would be define a top level menu like so

(easy-menu-define flycheck-menu flycheck-mode-map "Flycheck menu"
  '("Flycheck"
    ["Check current buffer" flycheck-buffer t]
    ["Clear errors in buffer" flycheck-clear t]
    ["Compile current buffer" flycheck-compile t]
    "---"
    ["Go to next error" flycheck-next-error t]
    ["Go to previous error" flycheck-previous-error t]
    ["Show all errors" flycheck-list-errors t]
    ["Google messages at point" flycheck-google-messages t]
    "---"
    ["Select syntax checker" flycheck-select-checker t]
    "---"
    ["Describe syntax checker" flycheck-describe-checker t]
    ["Read the Flycheck manual" flycheck-info t]))

This might not be a solution if you do not want to introduce another menu-bar item. Looking at the function minor-mode-menu-from-indicator in mouse.el it seems that it looks up for keybindings starting with [menu-bar] for getting the mode-line menu, that might also be interesting for you.

1

Note that you can supply any valid mode-line construct as the STRING / lighter value for a given mode's VARIABLE in minor-mode-alist.

So although this value is commonly just the name of the mode (or some appropriate abbreviation thereof), you can do more elaborate things such as including set text properties -- which can include a local-map property to specify a keymap for mouse clicks (see C-hig (elisp) Properties in Mode RET).

You might look at M-x find-variable RET mode-line-modes RET for an example (n.b. IIRC this variable is only in Emacs 24, where the complexity of the mode-line-format variable was broken out into independent sub-variables, to make the overall structure easier to understand/modify).

See C-hig (elisp) Mode Line Format RET for the full documentation.

phils
  • 71,335
  • 11
  • 153
  • 198