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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Elisp中获取变量的初始值?相关的知识,希望对你有一定的参考价值。

在Emacs Lisp中,是否有一个函数来获取由defvar启动的符号的初始值?像下面显示的some-function

(defvar var "initial value")
(setq var "changed value")
(some-function 'var)
=> "inital value"
答案

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

(defvar var "initial value")
(setq var "changed value")

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

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

另一答案

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

defcustom variables

使用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

请参阅elisp手册中的Defining Customization Variables部分,特别是上面讨论custom-reevaluate-setting函数的文档。

buffer-local variables

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

(setq indent-tabs-mode nil)
(default-value 'indent-tabs-mode)  ;; evaluates to t

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

(set-default 'indent-tabs-mode nil)
(default-value 'indent-tabs-mode)  ;; evaluates to nil

有关详细信息,请参阅elisp手册中的Introduction to Buffer-Local Variables部分。

另一答案

如果变量设置为buffer local valuesframe local values,请尝试:

(default-value 'var)

但是,如果有人使用setq-default更改默认值,您将获得新的默认值,而不是通过defvar设置的原始版本。来自documentation

此函数返回符号的默认值。这是在缓冲区和框架中看到的值,该缓冲区和框架没有自己的变量值。如果symbol不是缓冲区本地的,则这相当于symbol-value(参见Accessing Variables)。

另一答案

看起来@ tao-peng在这里找到了答案,但完整的故事是这样的:

defvar创建的符号通常只有它设置的值,以及可选的属性列表,最多通常有variable-documentationrisky-local-variable集,例如:

> (symbol-plist 'load-path)
(risky-local-variable t variable-documentation -587478)

另一方面,用defcustom创建的符号有更长的symbol-plist,包括standard-value属性,你可以这样得到:

> (get 'package-archives 'standard-value)
((quote (("gnu" . "http://elpa.gnu.org/packages/"))))

正如@ trey-jackson所指出的那样,对于具有缓冲局部值或帧局部值的符号,您可以使用以下内容获取原始值:

> (setq foo "bar")
> (make-variable-buffer-local 'foo)
> (setq foo "baz")
> (default-value 'foo)
"bar"
> foo
"baz"
另一答案

我们的方案:

;;;###autoload
(defun xorns-get-original-value (symbol)
  "Return SYMBOL's original value or nil if that is void."
  (if (boundp symbol)
    (eval (car (get symbol 'standard-value)))))

以上是关于如何在Elisp中获取变量的初始值?的主要内容,如果未能解决你的问题,请参考以下文章

elisp语法

如何更改片段中的主要活动变量

为啥 elisp 局部变量在这种情况下保持其值?

Elisp 03:变量

Elisp 列表包含一个值

如何在 elisp 中捕获 shell 命令的标准输出?