使用setq而不是custom.el设置变量的优点?


69

我看到很多人(扩展作者和其他人)通过setq以下示例提供配置示例:

(setq foo 'bar)

这些参数通常使用定义defcustom,因此可通过进行自定义custom.el

我通常custom.el用来设置它们。setq替代使用是否有任何优势,或者这两种方法大致等效?

Answers:


85

有些人可能认为它使用起来更简单setq。某些人可能认为它更加脆弱。实际上,在一般情况下这是幼稚的。

的确,对于某些用户选项,这并不重要。但是对于其他人而言,这确实很重要,并且setq对于这些选项来说是错误的方法。因此,作为一般规则,setq是错误的方法。

如果使用custom-set-variablescustomize-set-variable而不是setq,或者使用Customize用户界面(例如M-x customize-option),则可以确保该选项值所需的任何预期的初始化或更新代码将自动触发并根据需要运行。如果使用setq,则不会完成。

现在,大多数用户选项(尤其是为第三方库编写的大多数选项)也没有使用defcustom关键字:setand :initializesetq这对他们来说也无所谓。但是,许多普通的Emacs选项确实使用了这样的关键字,而对于那些这样做的人来说,这setq是不正确的。因此,如果您想使用Lisp代码而不是Customize UI来设置选项,那么最好使用custom-set-variablescustomize-set-variable代替setq。它从不伤人,有时会有所帮助。

但是我建议您同时做以下两件事:

  • 使用Customize UI而不是为此编写Lisp代码。

  • 定义变量custom-file,以便Customize将自定义内容写入该文件而不是您的init文件(~/.emacs)。IOW,请将您的手写初始化代码与Customize编写的自动代码分开。


5
我认为值得一提的是,即使使用:set和:initialize参数,如果setq在加载包之前被读取,setq仍然可以使用。
马拉巴巴2014年

2
@Willyfrog你可以投票!
赞恩·谢尔比

17
不确定那个德鲁。整个定制过程相当复杂。没有它,emacs系统将更加简单。自定义层与elisp不能很好地啮合。一方面,它按字母顺序对所有变量进行排序。同样,许多定制与变量(例如,钩子,键)无关,因此不能使用定制。因此,无论如何,您都会遇到手动删除代码的情况。
Xah Lee 2014年

4
@XahLee。好吧,我确定。;-)但是,自定义就是它。对于键,钩子,字体锁定关键字,显示表等而言,这并不是最好的选择。但是对于它所做的事情(选项和面孔),它做得很好。并不是说UI很棒,而是处理触发器,类型检查等很有帮助。我甚至希望程序员能(可选)使用的东西,像:typedefvar-我不认为它应该仅限于用户的选择。不幸的是,许多程序员在使用时都比较懒惰:type,并且结果不是很有帮助(这不是Customize的错)。
德鲁

1
数据点:在一年的大部分时间里,在我的3,300行Emacs初始化代码中,我一直被使用setq而不是customize-set-variable一次咬伤。(那是一次auto-revert-interval,我后来意识到setq 加载之前使用autorevert实际上比使用快得多customize-set-variable。)
Radon Rosborough

37

我之所以喜欢setqcustomize有几个原因:

  1. 首先,它允许以编程方式设置变量(如中所示(setq foo (calculate-foo)))。我一直在配置中使用此功能以保持干燥。对我来说,使用Emacs的全部重点是可编程性,并且该customize界面什么都不会妨碍。
  2. setq更适合于版本控制和代码组织。我将初始化分为几十个文件;如果所有内容都在一个大custom.el文件中,则快速查找和编辑设置将变得更加困难。
  3. 这是主观的,但对我而言,整个customize界面感觉就像90年代最糟糕的UI一样令人恐惧。我希望每天都可以使用Emacs的功能来编辑文本。

@Drew对:set和的一些细微之处提出了一些意见:initialize。我已经使用Emacs多年了,很少遇到这样的问题。当我这样做,可以很容易地换出setqcustom-set-variable在特定情况下。


10
1.您可以使用编程设置自定义变量customize-set-variable(s),这会更好,因为触发器会自动运行。2.您可以使用各种自定义命令在不同的层次结构中查看所有已设置和/或保存的变量,因此您可以自动获得不同组的组织,而不必在版本控制中使用单独的文件。3.变得更好了。如果您不喜欢UI,您仍然可以通过编程方式使用自定义,并通过交互式命令避免使用自定义模式来获得使用自定义的所有其他好处。
尼克·麦卡迪

23

使用setq代替的优点之一customize是可读性。可以根据自己的喜好随意注释每个自定义项,这可以提高IMO的可读性。也可以将相关的自定义分组在一起,以提高模块化。最后,我认为,浏览elisp缓冲区比浏览自定义UI和小部件更“容易”。

另一方面,自定义可让您轻松地恢复为默认值,当情况变得混乱时,这些默认值将毫无价值。

编辑:德鲁的答案提供了一个使用customize-set-variables的充分理由,它可以提供我指出的所有优点。但是,Customize UI不能像原始elisp那样轻松地在不同平台之间进行便携式配置。如果您需要变量具有与操作系统相关的设置,则在许多情况下,您将不得不回退到elisp。关于在elisp缓冲区中更轻松导航的观点仍然存在。


您也可以使用还原为默认值setq,只需注释掉该setq行并重新启动emacs。
T. Verron 2014年

3
是的,但是自定义可以还原,而无需重新启动。在尝试新设置时非常有用。
Vamsi 2014年

2
关于注释,定制界面确实允许您向更改的每个变量添加注释。
Andrew Swann 2014年

custom-set-variables “原始elisp”,我每天在多台计算机上使用它。只需将其复制到定制编写位置即可(如果您自己没有写过的话)。
Croad Langshan

<kbd> Mx Customize-* </ kbd>接口具有一个“注释”字段,该字段允许将注释与变量一起存储。
kdb

-1

另一种选择是使用John Wiegley的use-package。这提供了一种编程方式来配置与emacs 24+软件包初始化过程完美配合的软件包。这是自述文件中的用法示例:

(use-package color-moccur
  :commands (isearch-moccur isearch-all)
  :bind (("M-s O" . moccur)
         :map isearch-mode-map
         ("M-o" . isearch-moccur)
         ("M-O" . isearch-moccur-all))
  :custom (isearch-lazy-highlight t)
  :config (use-package moccur-edit))

关键是use包是一个宏,不会立即评估其参数。的:init:config在初始化过程的不同阶段的参数进行评估,使得可以在一个地方的每个封装的结构,但具有各部分执行在初始化适当阶段。

如果没有类似的东西,则use-package某些软件包需要将其初始化代码的一部分放在(package-initialize)后面,而将另一部分放在后面。如果您有很多这样的packegas,则必须对它们的初始化进行交织。

另一个好处use-package是,如果您将.emacs带到新计算机上,或者与其他用户共享配置,并且可以将所有初始化推迟到实际需要加载软件包时,它可以使用package.el自动安装缺少的软件包。

还有其他关键字参数,可以更好地控制初始化过程。

综上所述,定制的一大优势在于它可以向您显示在任何给定的软件包中要配置的内容。这就是我仍然将其用于许多包装的原因之一。


2
这实际上并不能回答问题。在您的答案中,您使用了setq,而没有说明原因。
J戴维·史密斯,J

3
我认为use-package它本身提供了模块化配置的优势,并且还可以在一处导入和配置软件包。但是是的,该示例正在使用setq。可以customize-set-variable在这里使用吗?我不确定。我们可以/应该将它(或customize-set-value)换成setq吗?
mike

4
请更改示例以使其使用:custom关键字。
Toon Claes
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.