Emacs Lisp中setq和setq-default的区别

112
我有一个问题关于Emacs Lisp。什么是 setqsetq-default 的区别?
教程说,setq本地缓冲区 生效,而 setq-default 会影响所有缓冲区。
例如,如果我在 init.el 文件中写下 (setq a-var a-vars-value),那么在启动 Emacs 并打开一个新缓冲区后,a-var 也会存在,并且其值为 a-vars-value。我原本以为它不应该在那里出现。看起来 setqsetq-default 没有区别。
请问我的理解有什么问题吗?
例如:
  1. 我在 init.el 中写下 (setq hello 123),然后在 shell 中运行 emacs abuffer,接着输入 "hello C-x C-e",会显示 "123"。使用同样的方法在所有新的缓冲区也会显示。

  2. 我在 init.el 中写下 (setq tab-width 4)。当我运行 tab-width C-x C-e 时,它显示 "8"(当前模式是 'Text')。但是,当我使用 (setq-default tab-width 4) 时,它显示 "4"。我无法解释这种现象。

1个回答

129

在Emacs中,一些变量是"缓冲区局部"的,这意味着每个缓冲区都可以有一个单独的值来覆盖全局默认值。 tab-width 是一个很好的缓冲区局部变量的例子。

如果变量是缓冲区局部的,则setq会在当前缓冲区设置其本地值,而setq-default会设置全局默认值。

如果变量不是缓冲区局部的,则setqsetq-default的作用相同。

在您的情况2中,(setq tab-width 4)将在当前缓冲区中将tab-width的缓冲区局部值设置为4,使得tab-width的全局默认值仍为8,因此当您在没有本地值的不同缓冲区中评估tab-width时,您会看到它是8。然后,当您将默认值设置为4时,该缓冲区会使用它,因为它仍然没有本地值。


当我执行(setq tab-width 4)时,在每个缓冲区中它总是为8。我不知道原因,似乎它没有生效。但是,当我使用(setq-default tab-width 4)时,它在每个缓冲区中都生效,我也不知道为什么 :( - ruanhao
1
tab-width 是一个缓冲区本地变量。因此,当你 (setq tab-width 4) 时,它只在当前缓冲区中设置为 4。所有其他缓冲区保留全局默认值 tab-width 为 8。当你 (setq-default tab-width 4) 时,你正在改变 tab-width 的全局默认值为 4,因此现在每个未定义自己的 tab-width 的缓冲区都有这个新的默认值。 - dfan
4
是的。请查看Emacs的启动顺序列表。读取初始化文件是第12步,打开初始缓冲区是第23步。 - dfan
1
啊,恍然大悟。所以当我(setq tab-width 4)时,没有缓冲区被初始化,也没有与 '(setq tab-width 4)' 相对应的特定缓冲区。在这种情况下,'init.el' 中的此配置有点无用,对吗? - ruanhao
3
如果你在init.el中设置(setq tab-width 4),那么这个设置只会应用于该缓冲区(即init.el文件)。如果你想让这个设置应用于所有新创建的缓冲区,那么使用(setq-default tab-width 4)可以实现。此外,如果你想为特定类型的文件创建一个模式,你可能会想要使用(setq tab-width 4),以免覆盖全局默认设置。 - Hemm
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接