Как я могу получить начальное значение переменной в Elisp? - PullRequest
4 голосов
/ 27 сентября 2010

В Emacs Lisp, есть ли функция для получения начального значения символа, инициализированного defvar?Как и some-function, показанное ниже:

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

Ответы [ 5 ]

10 голосов
/ 01 июля 2013

Обычно это невозможно (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

См. Раздел Определение параметров настройки в руководстве по elisp, в частности, обсуждение выше документации для функции custom-reevaluate-setting.

буферные локальные переменные

Локальные переменные буфера имеют значение по умолчанию (глобальное) и локальное значение буфера, которое может отличаться от глобального значения. Вы можете использовать функцию 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.

6 голосов
/ 28 сентября 2010

Emacs не запоминает начальное значение.Если вы оцениваете

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

в буфере *scratch*, "initial value" больше не доступен, полная остановка.

Если defvar было выполнено в загруженном файле, Emacs вспомнитоткуда он загружен;(symbol-file var 'defvar) возвращает имя файла, и вы можете получить исходное выражение, с которым была инициализирована переменная (но не исходное значение), при условии, что файл все еще существует.Это также доступно с помощью команды Mx find-variable .

4 голосов
/ 27 сентября 2010

Если для переменной задано локальные значения буфера или локальные значения кадра , попробуйте:

(default-value 'var)

Хотя, если кто-то использовал setq-default для изменения значения по умолчанию, вы получите новый, а не тот оригинал, который был настроен с помощью defvar. Из документации :

Эта функция возвращает символ по умолчанию значение. Это значение, которое видно в буферах и кадрах, которые не имеют свои собственные значения для этой переменной. Если символ не является локальным для буфера, это эквивалентно значению символа (см. Доступ к переменным ).

3 голосов
/ 11 октября 2012

Похоже, @ тао-пенг сам нашел здесь ответ, но полная история такова:

Символ, созданный с помощью defvar, обычно имеет только значение, которое ему задано, а также опционально список свойств, который, как правило, обычно имеет variable-documentation или, возможно, risky-local-variable, например ::100100

> (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"
0 голосов
/ 28 февраля 2018

Наше решение:

;;;###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)))))
...