Emacs Lisp 中 setq 和 setq-default 的区别

Posted

技术标签:

【中文标题】Emacs Lisp 中 setq 和 setq-default 的区别【英文标题】:The difference between setq and setq-default in Emacs Lisp 【发布时间】:2013-08-12 22:08:41 【问题描述】:

我有一个关于 Emacs Lisp 的问题。 setqsetq-default 有什么区别?

教程说setq本地缓冲区生效,而setq-default影响所有缓冲区。

例如,如果我在init.el中写了(setq a-var a-vars-value),我发现在启动Emacs并打开一个新的缓冲区后, a-var 也在那里,其值为 a-vars-value。我以为它不应该在那里。 setqsetq-default 之间似乎没有区别。

我的理解有问题吗?

例如:

    我在 init.el 文件中写了 (setq hello 123),并在 shell 中运行 emacs abuffer,然后我输入“hello Cx Ce”,它显示“123”。当我在所有新缓冲区中运行它时也会发生同样的情况。

    我在 init.el 文件中写了 (setq tab-width 4)。当我运行 tab-width C-x C-e 时,它显示“8”(当前模式为“文本”)。但是,当我使用 (setq-default tab-width 4) 时,它会显示“4”。我无法解释这种现象。

【问题讨论】:

【参考方案1】:

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

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

如果变量不是缓冲区局部变量,则 setqsetq-default 做同样的事情。

在您的情况 2 中,(setq tab-width 4) 在当前缓冲区中将 tab-width 的缓冲区本地值设置为 4,而将 tab-width 的全局默认值仍为 8,因此当您在另一个没有本地值的缓冲区,您会看到 8。然后,当您将默认值设置为 4 时,该缓冲区会拾取它,因为它仍然没有本地值。

【讨论】:

当我(设置制表符宽度为 4)并对其进行评估时,每个缓冲区中始终为 8。我不知道为什么。好像没有生效。但是当我使用 (sets-default tab-width 4) 时,它会在每个缓冲区中生效。我也不知道为什么:( tab-width 是一个缓冲区局部变量。所以当你(setq tab-width 4)时,它在当前缓冲区中只设置为4。所有其他缓冲区保留全局默认值 8 的 tab-width。当您 (setq-default tab-width 4) 时,您正在将全局默认值 tab-width 更改为 4,因此现在每个尚未定义 tab-width 的缓冲区本身都具有新的默认值. 是的。请参阅 emacs 的Sequence of Actions at Startup 列表。读取初始化文件是第 12 步,调出初始缓冲区是第 23 步。 啊,开明了。因此,当 i (setq tab-width 4) 时,没有初始化缓冲区,也没有对应于 '(setq tab-width 4)' 的特定缓冲区。在这种情况下,'init.el' 中的这个配置有点没用,对吗? @ruanhao 如果你(setq tab-width 4)在 init.el 中,那么它只适用于那个缓冲区(init.el)。如果您希望此更改应用于所有新缓冲区,则 (setq-default tab-width 4) 将完成此操作。此外,如果您想为特定类型的文件创建模式,您可能需要使用 (setq tab-width 4) 以免覆盖全局默认值。

以上是关于Emacs Lisp 中 setq 和 setq-default 的区别的主要内容,如果未能解决你的问题,请参考以下文章

.emacs 中区分大小写的 setq 无效

Emacs简单配置

Common Lisp宏中的词法绑定

emacs 修复 python 的制表符缩进

Emacs:全局启用空白模式

cad lisp脚本 修改