有几个类似的设置函数:
- set和setq
- set-default
- defcustom
- custom-set-value
- custom-set-variables
- customize-set-value
- customize-set-variable
那么,这些函数有什么区别呢?
如果我想要将我的偏好设置用于插件,以下情况使用哪种设置函数更好:
- 如果一个变量是由defcustom设置的,则哪个设置函数更好?
- 如果一个变量是由defvar设置的,则怎么做?
对于您的问题的简短回答是:
对于由defvar
定义的变量,请使用setq
或setq-default
。
对于由defcustom
定义的变量,请使用setq
、setq-default
或Customize
机制。
下面是详细的答案。
你将会用到以下函数:
set
是设置变量值的主要函数。
setq
是另一个版本,它自动引用其第一个参数。这很有用,因为几乎所有情况下都需要引用第一个参数。
有些变量不能全局设置。每次设置变量时,只有当前缓冲区被设置。如果你想模拟全局设置这个变量,可以使用set-default
或setq-default
。
包编写者使用的函数有:
defvar
允许包编写者定义一个变量并提供一些文档说明。这个函数不是必需的,但它使用户的生活更容易。
defcustom
是在defvar
基础上构建的。它告诉emacs它是一个变量,并允许开发者创建一个custom
接口来设置值。开发者可以说,像“这个变量只能包含'foo'或'bar'的值”之类的话。
设置变量有两种方式:
如果使用了defvar
,则用户只能通过在其.emacs
中使用set
函数(或变体)来设置值。
如果使用了defcustom
,可以通过set
(参见1)或使用Customize
来设置值。当使用自定义机制时,Emacs将生成一些代码,并将其放在custom-set-variables
中。用户不应该使用此函数。
C-h i
)。但是,就直觉而言,以下是一些重要差异:
set
是“低级”变量赋值。(setq foo bar)
是 (set (quote foo) bar)
的简写。(set-default foo bar)
的意思是“除非在当前缓冲区中有更明确范围的foo
定义,否则使用值bar”,并适用于所有缓冲区。defcustom
用于标记变量,表示用户可以安全地通过customize
功能修改它。custom-set-value
和customize-set-value
是指向同一个函数的两个名称。它们是使用customize
系统的便捷方法。custom-set-variables
和customize-set-variables
用于激活某些通过customize
定制的变量集合,如果我没记错的话。通常建议使用M-x customize
来更改设置。您可以自由地使用set
或setq
设置在您的.emacs
文件中定义的内容,但如果您后来通过customize
更改它,定制系统会警告您。
defcustom
通常只由编写用于分发的软件包的人使用,我认为除了在内部文件中使用customize-set-*
之外,没有人使用过它们。不管这些东西是否标记为与customize
一起使用,setq
在人们的初始化文件中都很常见,用于设置自己喜欢的内容。
我对所有这些并没有全面的了解,希望其他人能提供更多的信息,但我认为这是一个相当不错的概述 :P
set
和 setq
是用于分配任何类型变量的最低级别原语。set-default
和 setq-default
是emacs扩展,与缓冲区本地变量一起使用,允许设置新缓冲区使用的默认值。
3-7. 所有“自定义”内容是后来添加的,旨在支持用作用户首选项的变量的用户界面管理。defcustom
类似于 defvar
,但允许您指定选项层次结构中的位置,以及数据类型信息,以便UI可以将值显示为菜单,或自动将用户输入转换为适当的类型。custom-set-value
函数。custom-set-variables
由自定义UI在保存所有用户选项时使用。它列出了用户已从其默认值更改的所有变量。
6-7. custom-set-value
和 custom-set-variable
由自定义UI用于提示用户当前和默认值的选项变量,并将它们分配。通常情况下你不会自己调用它们。def...
构造声明全局变量。 set...
函数设置变量,无论是全局还是局部变量。当 x
既不是局部变量(当前函数的形式参数或由 let
表单或类似方式声明)也没有被 def...
表单定义时,您编写 (setq x 0)
将会导致字节编译器显示警告。Warning: assignment to free variable `x'
defvar
、defcustom
和 defconst
声明的变量是动态绑定的。也就是说,当你有一个结构时:
(let ((lisp-indent-offset 2))
(pp (some-function)))
函数some-function
将看到全局变量lisp-indent-offset
的更改。
当一个变量没有被动态绑定时,就像...
(let ((my-local-var 1))
(some-function))
如果my-local-var
没有全局值,则some-function
将无法看到已分配的值,因为它是按词法作用域作用的。
另一方面,动态作用域变量不会被捕获到词法闭包中。
更多细节请参见http://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html
defvar
而只是使用setq
,那么你只能在加载包后覆盖该值。但是,如果用户可以更改该值,则不应在包中仅使用setq
而不使用defvar
。如果使用编写正确的包,则使用setq
或custom
没有区别。 - Nicolas Dudeboutsetq
设置任何你想要的东西,它不会报错。如果使用了defvar
,那么当包被加载时,emacs
将意识到一个值已经被设置,并且不会采用defvar
中给定的默认值。 - Nicolas Dudebouteval-after-load
)才能添加到列表中,或者复制整个列表并添加我的元素(这就是自定义所做的)。 - Nicolas Dudeboutsetq
可以分配给多个变量,而set
只能分配给一个变量。 - gbrener