加载前Emacs setq

时间:2014-04-07 14:15:36

标签: emacs dot-emacs

自定义Emacs时,是否在加载包之前或之后设置相应的变量?

即,

(setq some-variable some-value)
(require 'some-package)

(require 'some-package)
(setq some-variable some-value)

在我看来,除非某些软件包在加载后明确要求init,否则大部分时间都可以工作。我是对的吗?

2 个答案:

答案 0 :(得分:4)

如果变量是用户选项,请在加载包之前执行此操作。该软件包包含定义该选项的defcustom,但如果变量已有值(例如,来自您的defcustom),setq将不会设置该值。

类似地,如果变量是不是用户选项的全局定义变量,即由包使用defvar定义。与defvar一样,defcustom不会覆盖现有值。

另一方面,根据变量,有时您希望在加载包之后更改其值。这完全取决于包的功能以及如何使用该变量。

无论我上面说过什么,IMO通常都是 坏主意 来改变全局变量值(无论选项与否) )在init文件中使用setq

  • 对于选项,最好使用自定义UI自定义它,或者在init文件中使用其中一个函数custom-set-variablescustomize-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)
    ))