自定义Emacs时,是否在加载包之前或之后设置相应的变量?
即,
(setq some-variable some-value)
(require 'some-package)
或
(require 'some-package)
(setq some-variable some-value)
在我看来,除非某些软件包在加载后明确要求init,否则大部分时间都可以工作。我是对的吗?
答案 0 :(得分:4)
如果变量是用户选项,请在加载包之前执行此操作。该软件包包含定义该选项的defcustom
,但如果变量已有值(例如,来自您的defcustom
),setq
将不会设置该值。
类似地,如果变量是不是用户选项的全局定义变量,即由包使用defvar
定义。与defvar
一样,defcustom
不会覆盖现有值。
另一方面,根据变量,有时您希望在加载包之后更改其值。这完全取决于包的功能以及如何使用该变量。
无论我上面说过什么,IMO通常都是 坏主意 来改变全局变量值(无论选项与否) )在init文件中使用setq
。
对于选项,最好使用自定义UI自定义它,或者在init文件中使用其中一个函数custom-set-variables
或customize-set-variable
(即,明确地,您自己)。这是因为定义选项的defcustom
可以使用“触发器”进行值初始化和更新(并且可以进行其他特殊处理)。并且给定的defcustom
可以依赖于评估其默认值表达式,以及在文件中出现的其他内容。
如果您只是使用setq
初始化或更新该选项,那么您可以绕过任何此类特殊处理,这可能不您想要的,并且可能会导致意外。
同样地,但一般来说不太重要,除非你确定自己在做什么,否则在非选项上使用setq
可能是个坏主意(即{{1} })变量。
我的建议: 使用自定义,但不要让它写入您的初始文件。相反,定义变量 defvar
(实际上,它是一个选项,但你不能真正使用它),以便Customize写入该单独的文件并保留您的init文件手动修改。 (您仍然可以在init文件中使用custom-file
。)
如果您这样做,您需要从初始文件加载文件customize-set-variable
。您可以决定在init文件中的哪个位置执行该操作,即init文件中的给定变量设置是在加载custom-file
之前还是之后(Customize管理的设置)。
答案 1 :(得分:1)
你说这两种情况通常都是可以接受的。但并非总是在特殊情况下。
您必须了解,例如,如果您在运行python-shell-interpreter
进程后设置*Python*
,则不会更改*Python*
可执行文件。您必须杀死*Python*
缓冲区并再次运行它才能使更改生效。
还有一些变量在文件加载时绑定,具体取决于另一个变量的值。因此,对基础变量的更改不会传播到派生值。只需阅读源代码即可查看。
因此,如果您将代码放在.emacs
中,除非模式文档说另一个(在手册中阅读有关Emacs加载过程的内容,在该阶段Emacs不会处理任何用户缓冲区)。
但是如果你在一些缓冲区处理之后改变变量 - 它可能不起作用。当Emacs处理用户缓冲区时,它可以初始化/填充内部缓存。很难找到这些缓存(您必须阅读源或文档)并了解重置或触发重新加载的方式(将其设置为nil
或调用某些mode-reinit
函数)。
某些软件包(如Gnus)允许干净卸载(gnus-group-exit
),因此您可以再次加载它,就像它之前没有加载一样......
在任何情况下,我都发现阅读Emacs源非常容易 - 如果你有问题,只需查看变量/函数声明,了解它是如何设置的,以及它使用的是什么。
这个示例来自我的.emacs
,我在加载前需要调整模式(因此,如果我更喜欢使用Cygwin和INFOPATH env var中的;
,则本机Emacs不使用:
):
;; Assume that cygwin-mount already activated.
(when (featurep 'cygwin-mount)
(setenv "INFOPATH" "/usr/share/info/:~/usr/share/info/:")
;; Redefine path-separator to UNIX to update Info-directory-list.
(let ( (path-separator ":") )
(require 'info)
(info-initialize)
))