1

When one wants to know which command is triggered by a keybinding, there is C-h k.

Is there a way to know which command is triggered by a click on a button?

For example, in notmuch-hello, I would like to know which command is triggered when I click on clear (Recent searches) to create a keybinding.

C-h k + click on clear only says that it invokes a widget, not what command the widget triggers.

There were several key-sequences:

at that spot runs the command widget-button-click
at that spot runs the command mouse-set-point

They're all described below.

at that spot runs the command widget-button-click (found in notmuch-hello-mode-map), which is an interactive byte-compiled Lisp function in ‘wid-edit.el’.

It is bound to and .

(widget-button-click EVENT)

Invoke the button that the mouse is pointing at.

at that spot runs the command mouse-set-point (found in global-map), which is an interactive byte-compiled Lisp function in ‘mouse.el’.

It is bound to and C-M-.

(mouse-set-point EVENT &optional PROMOTE-TO-REGION)

Move point to the position clicked on with the mouse. This should be bound to a mouse click event type. If PROMOTE-TO-REGION is non-nil and event is a multiple-click, select the corresponding element around point, with the resulting position of point determined by ‘mouse-select-region-move-to-beginning’.

Probably introduced at or before Emacs version 22.1.

C-h o notmuch-hello-mode-map:

notmuch-hello-mode-map is a variable defined in ‘notmuch-hello.el’.

Its value is shown below.

Keymap for "notmuch hello" buffers.

This variable may be risky if used as a file-local variable.

Value:

(keymap (keymap (4 . notmuch-hello-mode-transient) (15 . notmuch-hello-mode-transient) (32 . mda-pre-key) (120 . notmuch-bury-or-kill-this-buffer) (remap keymap (notmuch-tag-undo . undo))) (keymap (13 . widget-button-press) (down-mouse-1 . widget-button-click) (down-mouse-2 . widget-button-click) (backtab . widget-backward) (S-tab . widget-backward) (27 keymap (9 . widget-backward)) (9 . widget-forward)) keymap (remap keymap (undo . notmuch-tag-undo)) (106 . notmuch-search-transient) (71 . notmuch-poll-and-refresh-this-buffer) (27 keymap (61 . notmuch-refresh-all-buffers)) (61 . notmuch-refresh-this-buffer) (103 . notmuch-refresh-this-buffer) (109 . notmuch-mua-new-mail) (117 . notmuch-unthreaded) (122 . notmuch-tree) (116 . notmuch-search-by-tag) (115 . notmuch-search) (113 . notmuch-bury-or-kill-this-buffer) (118 . notmuch-version) (63 . notmuch-help)) 
1
  • @Gilles 'SO- stop being evil' Thank you for the edit. Commented Aug 31, 2024 at 13:13

2 Answers 2

4

Use C-h k, but click on the the thing you are interested in.

I had forgotten that all buttons created by the widget library execute a single command named widget-button-click. This command then looks up the correct command to run and then runs it. It’s necessary but a annoying when you are introspecting things.

When you find yourself in that situation, put the point on the button and use C-u C-x = to run what-cursor-position. This opens a buffer containing everything Emacs knows about the character at point. It includes various data from the unicode database about the character, and it also includes any text properties at that point. You want to look for either the button or action property. Either one can describe what to do when the thing is clicked on.

The button property often holds something that looks like an object:

(push-button :tag " Revert... " :help-echo "Show a menu with reset operations." :mouse-down-action ignore :action custom-reset :button-overlay #<overlay from 165 to 176 in *Customize Group: Emacs*> :from #<marker (moves after insertion) at 165 in *Customize Group: Emacs*> :to #<marker at 176 in *Customize Group: Emacs*>) 

This particular one came from the first button I spotted in a Customize buffer, rather than from notmuch-hello. Its a property list (aka plist). The :action property is custom-reset, which is the function that this button calls when clicked. The other properties of the button aren’t so relevant to your situation, but you can probably guess what they’re for.

Some other things that you can click on have an action property instead. This can name a function, or it sometimes contains the function body itself. If the value is just the function itself, then they’re pretty hard to read:

#[128 " r\306\307!q\210p\310 \210\311\211\312\211\312\313 \210\314\315!+\210\211\316\300\242!\317!)\210\207" [("(push-button :tag \" Revert... \" :help-echo \"Show a menu with reset operations.\" :mouse-down-action ignore :action custom-reset :button-overlay #<overlay from 165 to 176 in *Customize Group: Emacs*> :from #<marker\n (moves after insertion)\n at 165 in *Customize Group: Emacs*> :to #<marker at 176 in *Customize Group: Emacs*>)") default-directory buffer-read-only buffer-file-name buffer-undo-list inhibit-modification-hooks get-buffer-create "*Pp Eval Output*" kill-all-local-variables nil t erase-buffer run-hooks temp-buffer-setup-hook princ internal-temp-output-buffer-show inhibit-read-only standard-output] 7 "\n\n(fn &rest IGNORE)"] 

That particular button opens the window that shows the value of the button property I already mentioned in a new window. The really odd–looking stuff at the beginning is the compiled bytecode that will be executed when this function is called. Not super helpful.

Still other clickable buttons instead have a category property that leads you to more information. The category generally has an activate property that again contains either a function or the name of one.

And of course, once you have a function name you can use C-h f to look up what the function does and where it is defined.

7
  • 2
    The command is widget-button-click as the help display shows. That may not be what you meant (you probably meant which function in notmuch-hello is called to clear the search history), but that is the command that is called: it just happens to be implemented using the widget library which adds some layers of indirection to the call sequence before you get back into notmuch-hello. The function that clears the search history is notmuch-hello-insert-recent-searches - which as its name implies, does more than clear the search history. Commented Aug 30, 2024 at 14:34
  • 1
    This doesn't answer the question. Clicking on the button triggers some command, that's hardly surprising. The question is which command. Commented Aug 30, 2024 at 15:13
  • 1
    No, I deliberately answered the metaquestion of how to find the command that a button click will execute because I don't want to have to answer the same question for every single button in Emacs. Besides, I couldn’t even get a working buffer out of notmuch-hello until I installed notmuch and configured it, which I didn’t want to bother to do. I’d forgotten that all widget buttons just execute widget-button-click though, that is annoying. Commented Aug 30, 2024 at 15:46
  • 2
    @Gilles'SO-stopbeingevil' I disagree (at least for the current form of the answer): it answers the question completely - the answer is widget-button-click. If you were talking about the earlier one-line form of the answer, I agree that it was a bit too cryptic, although using C-h k, the OP was able to come up with the answer, even if he did not quite realize it. The most important point IMO is the one on the first liine: C-h k works for events, not just keys. Commented Aug 31, 2024 at 2:06
  • 1
    The only criticism of the answer I have (and it can be argued that it is off-topic: you cannot explain everything starting from first principles in an SE answer) is that in the "not super-helpful" case, the OP is basically stuck: it is often the case that these callbacks are fairly simple, so they are implemented as anonymous lambdas and after compilation, they are unrecognizable. Some guidance might be helpful for that case. Commented Aug 31, 2024 at 2:23
0

The action triggered by clicking on clear doesn't seem to be associated with a specific function. So you'll have to create a function that replicates this action:

(defun my-notmuch-clear-search-history () (interactive) (when (y-or-n-p "Are you sure you want to clear the searches? ") (setq notmuch-search-history nil) (notmuch-hello-update))) 
6
  • Why do you want to do this? Commented Aug 31, 2024 at 12:27
  • I was wondering why you would want to have this function. What are you going to do with it? It doesn't seem to be related to the question, it is not necessary for clicking the [clear] button, so it's not clear to me how/where/why you are going to use it. I'm basically asking what is the use case? Commented Aug 31, 2024 at 12:34
  • This function exactly does what clicking on clear does. And I think that none of notmuch functions does what clicking on clear does. I prefer avoiding using the mouse so I'll use a key associated with this function instead of clicking on clear. Commented Aug 31, 2024 at 12:38
  • I added this answer because it answers the specific issue raised by my question. But I accepted the other because it answered the generic question I asked. Commented Aug 31, 2024 at 12:42
  • The question you really asked is: Is there a way to know which command is triggered by a click on a button? and the answer is C-h k. You might have meant to ask a different question, but you did not. So, IMO, no, this does not answer the "specific issue" raised by your question: the accepted answer does . If you think there is more to discuss, please ask a new question (e.g. based on your comment about not using the mouse which is a perfectly reasonable question - the answer to that might involve explaining how you came up with that code). Commented Aug 31, 2024 at 12:55

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.