如何在Elisp中获取变量的初始值?

Tao*_*eng 4 emacs elisp

在Emacs Lisp中,是否有一个函数来获取符号的初始值defvar?像some-function如下图所示:

(defvar var "initial value")
(setq var "changed value")
(some-function 'var)
=> "inital value"
Run Code Online (Sandbox Code Playgroud)

Ric*_*sen 10

这通常是不可能的(Emacs不记得原始值),但有一些例外.

defcustom 变量

defcustom使用自定义系统定义和修改的变量将原始值,保存的值和自定义但尚未保存的值作为属性:

(defcustom foo 0 "testing")
(custom-set-variables '(foo 1))
(setq foo 2)
(customize-mark-as-set 'foo)
(setq foo 3)

(car (get 'foo 'standard-value))   ;; evaluates to 0
(car (get 'foo 'saved-value))      ;; evaluates to 1
(car (get 'foo 'customized-value)) ;; evaluates to 2
foo                                ;; evaluates to 3
Run Code Online (Sandbox Code Playgroud)

请参阅elisp手册中的" 定义自定义变量"部分,特别是上面有关该custom-reevaluate-setting函数文档的讨论.

缓冲区局部变量

缓冲区局部变量具有默认(全局)值和可能与全局值不同的缓冲区本地值.您可以使用该default-value函数获取默认值:

(setq indent-tabs-mode nil)
(default-value 'indent-tabs-mode)  ;; evaluates to t
Run Code Online (Sandbox Code Playgroud)

但是,可以更改默认值,Emacs将不记得原始默认值:

(set-default 'indent-tabs-mode nil)
(default-value 'indent-tabs-mode)  ;; evaluates to nil
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅elisp手册中的" 缓冲区局部变量简介"部分.


Gil*_*il' 6

Emacs不记得初始值.如果你评价

(defvar var "initial value")
(setq var "changed value")
Run Code Online (Sandbox Code Playgroud)

*scratch*缓冲区中,"initial value"不再可用,完全停止.

如果defvar在加载的文件中执行,Emacs会记住它从哪里加载; (symbol-file var 'defvar)返回文件名,你可以得到一个初始化变量的原始表达式(但不是原始值),假设文件仍然存在.这也可以通过命令获得M-x find-variable.

  • 公认.幸运的是,我发现所需的变量是由`defcustom`而不是`defvar`定义的.`defcustom`在其属性列表中存储符号的标准值. (5认同)

Tre*_*son 5

如果变量设置为具有缓冲区本地值帧本地值,请尝试:

(default-value 'var)
Run Code Online (Sandbox Code Playgroud)

不过,如果有人曾经setq-default更改过默认设置,您将获得新的默认设置,而不是通过defvar. 从文档中:

该函数返回符号的默认值。这是在没有自己的该变量值的缓冲区和帧中看到的值。如果符号不是缓冲区本地的,则这相当于符号值(请参阅访问变量)。