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

时间:2015-07-14 23:35:35

标签: emacs dot-emacs

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

(setq visible-bell t)

(visible-bell t)

两者似乎都有效。

但是

(desktop-save-mode 1)

有效,而

(setq desktop-save-mode 1)

请问这是为什么?

4 个答案:

答案 0 :(得分:4)

他们是不同的,因为他们是不同的:)

(setq visible-bell t)

将值t分配给名为visible-bell变量

(visible-bell t)

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

(虽然在当前版本的Emacs中默认情况下没有visible-bell功能,所以对我来说这并不是显而易见的实际以您的思维方式工作?但是,假设是你确实有这样一个功能的那一刻......)

Emacs Lisp是一个'Lisp-2',意味着它有变量和函数的单独名称空间,因此你可以 - 并且通常 - 有一个变量和一个具有相同名称的函数。引用哪一个总是隐含在代码的上下文中(例如setq总是引用变量)。

简而言之,这两段代码正在做着截然不同的事情。这并不意味着它们不能具有相同的效果(例如,函数可能只是设置变量的值);但是,实际情况是否完全取决于函数的定义。

1 实际上第一行代码是也是调用函数 2 :它正在调用setq并将其传递给它参数visible-bellt以及setq然后根据其参数设置值。希望你现在开始看到lisp语法是如何工作的?

2 严格来说,setq实际上是一种“特殊形式”而不是一种功能,特殊形式更接近宏而不是功能;但这些区别对于这个Q& A来说并不重要。

答案 1 :(得分:3)

其他人已经告诉你关于setq做什么以及变量与功能的基本观点。

Wrt visible-bell 本身:

  1. 在我知道的任何Emacs版本中都有与Emacs一起提供的无功能 visible-bell,并且从未有过。 (我已经通过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 RETC-h v RET visible-bell RET,然后单击customize链接)或在init文件中使用Lisp代码。

  5. 如果你使用Lisp代码,那么使用其中一个函数(不是setq):

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

    使用C-h f后跟每个函数名称,以查看有哪些(次要)差异。

答案 2 :(得分:1)

这里有3个问题。

  1. 在Emacs Lisp中,相同的符号可以是变量和函数。
  2. 在桌面保存模式的情况下,它是一个功能,但也是一个变量。

    因为它是一个功能,所以你可以打电话

    (desktop-save-mode 1)
    

    因为它是一个变量,所以你要设置值

    (setq desktop-save-mode t)
    

    您可以定义自己的函数以及同名的变量来测试它。

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

    1. 现在,第二个问题。通常,对于激活次模式的函数(命令),惯例是正整数应该意味着将其打开,否则关闭。
    2. 此外,对于激活次要模式的命令,通常会有一个同名的变量,值为t或nil,以指示模式是否开启。

      1. 现在,还有第三期。对于激活模式的命令,在emacs 24左右之前,按照惯例,如果没有给出arg,则命令切换当前状态。
      2. 由于上述所有问题,这个问题令人困惑。你可能会在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代码中调用。 (当作为命令以交互方式调用时,它会切换。)

        最后,总是调用describe-function或describe-variable来阅读doc。

答案 3 :(得分:0)

set set(具有自动引用功能的“set”)用于为变量赋值。在这个例子中,它显然不是必需的,因为正如你所提到的,省略它适用于第一组例子。

基本上,visible-bell是一个变量,你可以为它赋值“t”以启用可见的铃声。

但是,桌面保存模式是一个交互式功能,所以你不要使用setq为它赋值,你可以用参数调用它。

当你不确定是什么时,要做的一件好事就是使用内置的帮助功能:

# include <iostream>
using namespace std;

//function swaps references, 
//takes reference to int as input args and swap them
void swap(int& a, int& b)
{
    int c=a;
    a=b;
    b=c;
}

int main(void)
{
    int i=5,j=7;

    cout<<"Before swap"<<endl;
    cout<<"I:"<<i<<"J:"<<j<<endl;
    swap(i,j);
    cout<<"After swap"<<endl;
    cout<<"I:"<<i<<"J:"<<j<<endl;
    return 0;

}

这将返回可见铃声的信息 - 注意命令中的“v”是因为它是一个变量。如果要搜索有关函数的信息,可以执行以下操作:

C-h v visible-bell RET

顺便提一下,在这种情况下,桌面保存模式也是一个变量,但它是一个只读变量,用于确定是否启用了桌面保存模式,因此尝试更改它将不起作用。