为什么有些Emacs功能不能通过'M-x'使用?

为什么有些Emacs功能不能通过'M-x'使用?,emacs,Emacs,告诉我我可以使用set face属性设置Emacs的字体大小: (设置面属性“默认为零:高度100”) 注释显示,您无法使用M-x运行设置面属性: 相反,您必须使用M-:: 为什么有些命令,如设置面属性,不能通过M-x使用? M-x绑定到命令,该命令允许您键入命令的名称并运行该命令 M-:绑定到命令,该命令允许您键入包含函数的任意S表达式调用并计算它 可以使用M-::调用的函数用于实现Emacs功能、自定义(例如在.Emacs中)和插件。函数参数通常通过在S表达式中调用函数来传递 如果任

告诉我我可以使用
set face属性设置Emacs的字体大小

(设置面属性“默认为零:高度100”)
注释显示,您无法使用M-x运行
设置面属性

相反,您必须使用M-::

为什么有些命令,如
设置面属性
,不能通过M-x使用?

  • M-x绑定到命令,该命令允许您键入命令的名称并运行该命令
  • M-:绑定到命令,该命令允许您键入包含函数的任意S表达式调用并计算它
可以使用M-::调用的函数用于实现Emacs功能、自定义(例如在
.Emacs
中)和插件。函数参数通常通过在S表达式中调用函数来传递

如果任何函数的定义中有表单,那么它也可以是命令。交互式表单描述了函数作为命令调用时应如何获取其参数。例如,如果函数在其定义中有
(交互式“bgivemeabuffer:”)
,那么该函数将可以用M-x调用。当用户使用M-x调用函数时,Emacs将提示用户输入缓冲区名称(因为
b
),并且他们键入的名称将作为参数传递给函数

使函数成为命令的目的是使最终用户调用它变得容易,而不仅仅是Emacs Lisp程序员。命令(使用M-x运行)更易于通过以下方式交互运行:

  • 您不必在命令名周围加上
    ()
    ,使其成为有效的S表达式
  • 参数可以自动传递(例如光标位置),也可以提示您输入参数,这样您就不必记住需要哪些参数
  • 当提示输入参数时,您可以自动完成它,因为
    交互式
    表单(如
    b
    )指定了预期的输入类型
无法使用M-x调用函数
set face attribute
,原因是其定义不包含
interactive
表单,因此
set face attribute
不是命令。必须在S表达式中将其作为普通函数调用。您可以使用M-:,从minibuffer中执行此操作,也可以使用其他任何一种方法从其他位置执行此操作



对普通函数和命令之间的区别有一个简短的、不同措辞的解释。解释了一些不在此答案中的细节。

此问题是从中的问题扩展而来的。将其放在另一个问题中的主动性很好。从技术上来说,您的答案很好,但是,为了完整性,我要补充一点,从用户体验的角度来看,将所有函数作为命令公开是不明智的——这会使名称空间变得混乱,并使自动完成变得不那么有用。因此,大多数功能都不能通过M-x使用(在我看来,仍然有太多的命令需要人类记住;)