为啥某些 Emacs 函数不能通过 `M-x` 使用?

Posted

技术标签:

【中文标题】为啥某些 Emacs 函数不能通过 `M-x` 使用?【英文标题】:Why are some Emacs functions not available via `M-x`?为什么某些 Emacs 函数不能通过 `M-x` 使用? 【发布时间】:2015-05-25 19:50:24 【问题描述】:

This Stack Overflow answer告诉我可以用set-face-attribute设置Emacs的字体大小:

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

cmets 显示您无法使用 M-x 运行 set-face-attribute

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

运行它

为什么某些命令(例如 set-face-attribute)无法通过 M-x 使用?

【问题讨论】:

这个问题是从DavidSthis comment中的问题扩展而来的。 【参考方案1】: M-x 绑定到命令execute-extended-command,它允许您输入命令 的名称并运行它。 M-: 绑定到命令 eval-expression,它允许您键入包含 函数 调用的任意 S 表达式并对其求值。

您可以使用 M-: 调用的函数用于实现 Emacs 功能、自定义(例如在您的 .emacs 中)和插件。函数参数通常通过在 S 表达式中调用函数来传递。

如果任何函数在其定义中具有interactive 形式,则它可以是命令。 interactive 形式描述了函数在作为命令调用时应如何获取其参数。例如,如果函数在其定义中有(interactive "bGive me a buffer: "),那么该函数将可以用M-x 调用。当用户使用 Mx 调用函数时,Emacs 将提示用户输入缓冲区名称(因为b),他们键入的名称将作为参数传递给函数。

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

您不必将命令名称用() 括起来以使其成为有效的 S 表达式。 参数可以自动传递(例如光标位置),或者系统会提示您输入参数,这样您就不必记住需要哪些参数。 当提示输入参数时,您可以自动完成它,因为interactive 表单的code characters(如b)指定了预期的输入类型。

你不能用 M-x 调用函数set-face-attribute 的原因是它的定义不包含interactive 形式,所以set-face-attribute 不是命令。您必须在 S 表达式中将其作为普通函数调用。您可以使用 M-: 从 minibuffer 执行此操作,或者使用其他任何 ways of evaluating code 从其他地方执行此操作。


Emacs Mini Manual → Concepts → Command 对普通函数和命令之间的区别进行了简短的、不同措辞的解释。 Relationship between Emacs functions and commands 解释了这个答案中没有的一些细节。

【讨论】:

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

以上是关于为啥某些 Emacs 函数不能通过 `M-x` 使用?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Emacs更改文件的读/写模式?

Mac OSX、Emacs 24.2 和 nrepl.el 不工作

emacs建议恢复文件,但我错过了:如何让它提示?

为啥我的带有 ^ 的 Emacs 正则表达式不能匹配行的开头?

emacs 高亮

为啥 Cython 编译器会生成带有后缀“cpython-35m-x86_64-linux-gnu.so”的 so