Emacs M-x commands for invoking “GUI-style” menus

2020-03-01 16:24发布

问题:

Question: How could I find out the M-x equivalent commands for doing GUI-based operations in Emacs, in those cases where my Emacs-variant uses OS-specific desktop functionality?

Background: Conventional understanding states that everything in Emacs is a command, and that commands can be invoked via M-x, as long as you know the name of the command. Assuming this statement is correct, what is the way to find the name of the commands used to trigger the "GUI-style" menus in a "desktop" based Emacs variant?

For example, if I were to mouse-select the File menu to open a file, the OS-specific "GUI" style file-open dialog pops up, waiting for my input.

How could I find out the M-x equivalent command for doing the exact same thing?

I thought that describe-key would tell me what I needed to know, but it's indication to use:

M-x menu-find-file-existing

doesn't invoke the "GUI" style file-open dialog. Instead, it uses the Emacs internal non-GUI-OS-neutral variant.

回答1:

You need to trick Emacs into thinking that the keyboard was not being used, which is not as intuitive as tricking it into thinking that the mouse was used. :)

(defadvice find-file-read-args (around find-file-read-args-always-use-dialog-box act)
  "Simulate invoking menu item as if by the mouse; see `use-dialog-box'."
  (let ((last-nonmenu-event nil))
    ad-do-it))

Tested on Emacs 22.2.1 on WinXP. I believe the paradigm has been around for a while, though, so it should work on older Emacs. No clue if XEmacs works similarly or not.



回答2:

Wow, I'm glad you asked that. I've been meaning for a while to look it up myself.

C-h k followed by the menu choice will tell you this. Here, for example, is what you get from choosing menu/edit/paste:

<menu-bar> <edit> <paste> runs the command clipboard-yank
  which is an interactive compiled Lisp function in `menu-bar.el'.
It is bound to <paste>, <f18>, <menu-bar> <edit> <paste>.
(clipboard-yank)
Insert the clipboard contents, or the last stretch of killed text.

If you want the details, follow the link for menu-bar-el to the LISP source:

(defun menu-find-file-existing ()
  "Edit the existing file FILENAME."
  (interactive)
  (let* ((mustmatch (not (and (fboundp 'x-uses-old-gtk-dialog)
                  (x-uses-old-gtk-dialog))))
     (filename (car (find-file-read-args "Find file: " mustmatch))))
    (if mustmatch
    (find-file-existing filename)
      (find-file filename))))