Why are some Emacs functions not available via `M-

2019-01-15 06:48发布

问题:

This Stack Overflow answer told me that I can set Emacs’s font size with set-face-attribute:

(set-face-attribute 'default nil :height 100)

The comments reveal that you can’t run set-face-attribute with M-x:

Instead, you have to run it with M-::

Why are some commands, like set-face-attribute, not available via M-x?

回答1:

  • M-x is bound to the command execute-extended-command, which lets you type the name of a command and runs it.
  • M-: is bound to the command eval-expression, which lets you type an arbitrary S-expression containing function calls and evaluates it.

Functions, which you can call with M-:, are used to implement Emacs features, customizations (such as in your .emacs), and plugins. Function arguments are normally passed by calling the function in an S-expression.

Any function can also be a command if it has an interactive form in its definition. The interactive form describes how the function should get its arguments when called as a command. For example, if the function has (interactive "bGive me a buffer: ") in its definition, then the function will be callable with M-x. When the user calls the function with M-x, Emacs will prompt the user for a buffer name (because of the b), and the name they type will be passed as an argument to the function.

The point of making a function a command is to make calling it easy for end-users, not just for Emacs Lisp programmers. Commands (run with M-x) are easier to run interactively in these ways:

  • You don’t have to surround the command name with () to make it a valid S-expression.
  • Arguments can be passed automatically (such as the cursor position), or you can be prompted for them so you don’t have to remember what arguments are needed.
  • When prompted for an argument, you can auto-complete it, because the interactive form’s code characters (like b) specify what type of input to expect.

The reason you can’t call the function set-face-attribute with M-x is that its definition does not contain an interactive form, and so set-face-attribute is not a command. You must call it as a plain function, in S-expressions. You can do that from the minibuffer with M-:, or from other places with any of the other ways of evaluating code.


Emacs Mini Manual → Concepts → Command has a short, differently-worded explanation of the difference between normal functions and commands. Relationship between Emacs functions and commands explains some details not in this answer.



标签: emacs