使用 "setq" 和不使用 Emacs 设置有什么区别?



非常简单的问题,但让我困惑了一段时间:

(setq visible-bell t)

(visible-bell t)

都可以

,

(desktop-save-mode 1)

工作,而

(setq desktop-save-mode 1)

我可以问一下这是为什么吗?

它们不同,因为它们不同:)

(setq visible-bell t)

将值t赋值给变量命名为visible-bell

(visible-bell t)

调用函数1命名为visible-bell(并传递值t作为参数)。

(虽然在当前版本的Emacs中默认没有visible-bell函数,所以对我来说这是实际上按您的方式工作并不明显?但是,现在假设您确实有这样一个函数…)

Emacs Lisp是'Lisp-2',这意味着它为变量和函数提供了单独的命名空间,因此你可以——而且通常是这样做的——有一个变量和一个函数具有相同的名称。在代码的上下文中,被引用的对象总是隐式的(例如,setq总是指向一个变量)。

简而言之,这两段代码在做非常不同的事情。这并不意味着它们不能具有相同的效果(例如,函数可以简单地设置变量的值);但是否真的是这样完全取决于函数的定义。


1实际上第一行代码也是调用函数2:它调用setq并传递给它两个参数visible-bellt,然后setq根据它的参数设置值。希望你现在已经开始了解lisp语法是如何工作的了?

2严格来说,setq实际上是一个"特殊形式"而不是一个函数,特殊形式更接近于宏而不是函数;但这些区别对这个问题来说并不重要。

其他人已经告诉了您setq的基本要点以及变量与函数的区别。

Wrt visible-bell 本身:

  1. 没有功能 visible-bell与Emacs交付,在任何Emacs版本我知道,从来没有。(我回顾了Emacs 20,根据记忆,我相信从一开始就是如此。只有变量 visible-bell

    所以正如@phils所建议的,不清楚你说的是真的:"似乎都有效"。除非你加载的一些额外代码定义了该名称的函数(然后我们没有办法对它进行注释,没有它可以看到),计算(visible-bell t) 会引发一个未定义(void)函数错误

  2. 变量visible-bell不仅仅是一个变量。它是一个用户选项,并且至少从Emacs 20开始就是这样。

  3. 您应该而不是,一般情况下,只需使用setq来更改用户选项的值。在许多情况下,如果你这样做,你不会陷入麻烦,但有时你会,这不是一个好习惯。

    setq不执行任何可能适合给定用户选项的特殊初始化或更新操作。它不用于用户选项。或者更确切地说,用户选项不是为setq准备的——它们可能比setq所能提供的更复杂。

  4. 应该使用自定义来代替setq。要么以交互方式(M-x customize-option RET visible-bell RET,或C-h v RET visible-bell RET,然后单击customize链接),要么在初始化文件中使用Lisp代码。

  5. 如果您使用Lisp代码,请使用以下函数之一(不是setq):

    • customize-set-variable
    • customize-set-value
    • custom-set-variables

    使用C-h f跟在每个函数名后面,看看它们有什么(微小的)区别。

这里有三个问题。

  1. 在Emacs Lisp中,同一个符号既可以是变量,也可以是函数。

在桌面保存模式下,它既是一个函数,也是一个变量。

因为它是一个函数,所以你可以调用

(desktop-save-mode 1)

因为它是一个变量,所以你给它设置value

(setq desktop-save-mode t)

你可以定义你自己的函数,也可以定义一个同名的变量来测试它。

注意:函数的实参应该是什么或者变量的值应该是什么取决于函数或变量。

现在,第二个问题。一般来说,对于激活次要模式的函数(命令),约定是一个正整数应该意味着打开它,否则关闭。

此外,对于激活次要模式的命令,通常有一个相同名称的变量,值为t或nil,以指示模式是否打开。

现在,还有第三个问题。对于激活模式的命令,在emacs 24之前,按照惯例,如果没有给定参数,则命令切换当前状态。

由于以上所有原因,这个问题令人困惑。你可能会在init中看到这样的东西:

(desktop-save-mode 1) ; correct. To turn on.
(desktop-save-mode) ; Confusing. Should take value 1 to turn on. Usually works because by default it's off.
(desktop-save-mode t) ; wrong. Take value of positive integer to turn on.
(desktop-save-mode nil) ; Confusing. Value should be integer
(setq desktop-save-mode t) ; wrong. Shoud call function instead
(setq desktop-save-mode nil) ; wrong. Shoud call function instead
(setq desktop-save-mode 1) ; wrong. Shoud call function instead. Besides, only t and nil make sense

所以,有很多困惑。在emacs 24(或23.x)中,约定改变了,如果它没有接收到值,则在elisp代码中调用它时将打开。(当作为命令交互调用时,它会切换。)

最后,总是调用description -function或description -variable来读取文档。

setq(具有自动引用功能的"set")用于为变量赋值。在本例中,它显然不是必需的,因为正如您提到的,省略它对于第一组示例有效。

基本上,visible-bell是一个变量,你给它赋值"t"来启用visible bells。

然而,桌面保存模式是一个交互函数,所以你不用setq给它赋值,你可以用参数调用它。

当你不确定某事是什么的时候,最好使用内置的帮助功能:

C-h v visible-bell RET

这将返回可见bell的信息——注意命令中的"v"是因为它是一个变量。如果您想搜索关于某个函数的信息,您可以这样做:

C-h f desktop-save-mode RET

顺便说一下,在这种情况下,desktop-save-mode也是一个变量,但它是一个只读变量,用于确定是否启用desktop-save-mode,因此尝试更改它将不起作用

最新更新