我还是在纠结这个问题:什么情况下必须使用setq-default?
那么对那些既能使用setq
,也能使用setq-default
的var来说,应该尽量使用setq
还是setq-default
?
谢谢各位
我还是在纠结这个问题:什么情况下必须使用setq-default?
那么对那些既能使用setq
,也能使用setq-default
的var来说,应该尽量使用setq
还是setq-default
?
谢谢各位
setq
和 setq-default
作用不一样,不存在「应该尽量用哪个」这种情况,需要用哪个就用哪个。
普通的变量只要一个值,setq-default
没有意义,应该直接用 setq
。
对于 buffer local 变量,这样的变量每一个 Buffer 都有一个独立的值,因为不是每一个 buffer 都主动会设置它,所以需要有一个「初始值」或者「默认值」或者「全局值」,创建新 buffer 会自动继承这个值,如果需要修改这个「默认值」就只能用 setq-default
;如果需要修改这个变量在当前 buffer的值就只能用 setq
。所以当使用 (setq-default foo ...)
时,你确认
foo
是个 buffer-local 变量foo
的「默认值」普通的变量会变成 buffer-local 变量,当你用 defvar-local
/ make-local-variable
/ setq-local
时。
谢谢。
我看到有些配置里会对不是buffer-local的变量也使用setq-default
。所以产生了以前那个以及这个问题。
另外file-local
变量是不是buffer-local
变量?换句话说我怎么判断一个变量是不是buffer-local
的?看docstring吗?
让我在意这点的是 Default Value (GNU Emacs Lisp Reference Manual) 里的一段话:
For example, you could use
setq-default
to change the default setting ofparagraph-start
for most buffers; and this would work even when you are in a C or Lisp mode buffer that has a buffer-local value for this variable.
我从哪儿也没看出来 paragraph-start
是个buffer-local变量啊……
看源码 写代码
而不是
想代码 写代码
这得看是在哪个 buffer 中,C、Org 模式的 buffer 中 paragraph-start
是 buffer-local 的,其它 buffer 中它不是 buffer-local 的。
有些变量譬如 tab-width
和 mode-line-format
的 docstring 会提示
Automatically becomes buffer-local when set.
这不是说 tab-width
是个 buffer-local 变量,是不是 buffer-local 需要首先指明哪个 buffer 才有意义,
回到你的问题,某个 buffer 中
paragraph-start
不是 buffer-local 的,setq
和 setq-default
效果相同,修改全局值;paragraph-start
是 buffer-local 的,setq
修改这个 buffer-local 值,setq-default
修改全局值;所以我的迷茫点也在此处……就是我要的到底是什么。
以及如果在该使用setq
的时候使用了setq-default
,可能会造成什么影响?
我能预见的就是我将会设置一个本来不该设置的默认值,然后就各种乱套……
自然就是可能达不到你想要的目的呗
下次等你遇到了具体的例子再谈论更好些。
事实上我遇到的都是一些“模棱两可”的变量, 比如magit-diff-refine-hunk
, smex-history-length
, smex-save-file
这类的,我见过有人用setq
, 也见过有人用setq-default
……
可能两者都是对的,用哪一个取决于你想达到的目的(或者需要强调的内容)。不是说一个变量就只能用(或最好用) setq
,而不能也用(或最好不用)setq-default
,或者反过来。
这个例子很好,因为我也设置了它(大致如下[1]),我想修改它的值,而我的用法是错误的
(with-eval-after-load "magit"
(setq magit-diff-refine-hunk t))
正确的选择是 setq-default
,上面的代码没有考虑过 buffer-local 的情况,只是 setq
出问题条件比较苛刻:
magit-diff-refine-hunk
的 buffer-local 值,一般是通过 File / Directory local variable。如果你的 init.el
像下面这样写,同样是 setq
却不会有问题,因为它没有机会满足上面的条件
(require 'magit)
(setq magit-diff-refine-hunk t)
只是为了强调 magit-diff-refine-hunk
有时会是 buffer-local 的,而你想设置默认值,可以用 setq-default
。
[1] 我的 Magit 的全部设置如下(相关的设置等价于上面第一段代码)
package-archives
用 setq
没什么好说的,这个变量不存在 buffer-local 的情况;mode-line-format
这种变量「Automatically becomes buffer-local when set.」,如果用户需要设置一个公共的 Mode Line,就得用 setq-default
magit-diff-refine-hunk
这种变量偶尔作为 buffer-local,当它不是 buffer-local 时,setq
和 setq-default
效果相同,都是修改默认值;当它是 buffer-local 时,setq-default
设置默认值,setq
设置 buffer-local 值看到这里你这个帖子比我刚看到它时的意义多了那么一点点,不是”完全没什么好讨论的”了。不过很显然你对这两个有了基本的了解之后,用出问题的可能就非常小了,这时候再使劲想什么edge case下应该怎么用,只是过度、过早优化。因为它俩只是工具,也不会帮你提高elisp水平什么的。
他应该较真儿的是buffer local的实现