Когда вы устанавливаете переменной значение, а затем закрываете и перезапускаете Emacs, это значение не восстанавливается автоматически. Обычно пользователи устанавливают обычные переменные в своих файлах запуска или используют Customize (см. Настройки кастомизации) для постоянной установки пользовательских опций, а различные пакеты имеют различные файлы для хранения данных (например, Gnus хранит это в .newsrc.eld, а библиотека URL хранит файлы cookie в ~/.emacs.d/url/cookies).
Для вещей, находящихся между этими двумя крайностями (то есть конфигурация, которая помещается в файл запуска, и массивное состояние приложения, которое помещается в отдельные файлы), Emacs предоставляет механизм для репликации данных между сессиями, называемый переменные нескольких сессий. (Этот механизм может быть недоступен на всех системах.) Чтобы дать вам представление о том, как они должны использоваться, вот небольшой пример:
(define-multisession-variable foo 0)
(defun my-adder (num)
(interactive "nAdd number: ")
(setf (multisession-value foo)
(+ (multisession-value foo) num))
(message "The new number is: %s" (multisession-value foo)))
Это определяет переменную foo и связывает ее со специальным объектом переменной нескольких сессий, который инициализируется значением '0' (если переменная еще не существует из предыдущей сессии). Команда my-adder запрашивает у пользователя число, прибавляет его к старому (возможно, сохраненному значению) и затем сохраняет новое значение.
Этот механизм не предназначен для использования с большими структурами данных, но он должен быть производительным для большинства значений.
Этот макрос определяет name как переменную нескольких сессий и присваивает ей initial-value, если этой переменной ранее не было присвоено значение. doc — это строка документации, а в args можно использовать несколько именованных аргументов:
:package package-symbolЭтот именованный аргумент указывает, что переменная нескольких сессий принадлежит пакету, указанному в package-symbol. Комбинация package-symbol и name должна быть уникальной. Если package-symbol не указан, по умолчанию используется первый «сегмент» имени символа name, то есть часть его имени до первого символа '-'. Например, если name — это foo, а package-symbol не указан, package-symbol по умолчанию будет foo.
:synchronized boolПеременные нескольких сессий могут быть синхронизированы, если bool не равен nil. Это означает, что если запущены две параллельные инстанции Emacs, и другая инстанция изменяет переменную нескольких сессий foo, текущая инстанция Emacs получит эти измененные данные при обращении к значению. Если synchronized равен nil или отсутствует, этого не произойдет, и значения во всех сессиях Emacs, использующих эту переменную, будут независимы друг от друга.
:storage storageИспользуйте указанный метод storage. Это может быть либо sqlite (в Emacs, скомпилированном с поддержкой SQLite), либо files. Если не указано, по умолчанию используется значение переменной multisession-storage, описанной ниже.
Эта функция возвращает текущее значение variable. Если эта переменная ранее не была получена в текущей сессии Emacs или если она была изменена извне, она будет прочитана из внешнего хранилища. В противном случае возвращается текущее значение в этой сессии. Ошибка при вызове этой функции для переменной, которая не является переменной нескольких сессий.
Значения, полученные через multisession-value, могут не быть eq друг другу, но они всегда будут equal.
Это обобщенная переменная (см. Обобщенные переменные), поэтому способ обновления такой переменной — это, например:
(setf (multisession-value foo-bar) 'zot)
Только значения Emacs Lisp, имеющие читаемый синтаксис вывода (см. Представление и синтаксис чтения), могут быть сохранены таким образом.
Если переменная нескольких сессий синхронизирована, ее установка может обновить значение в первую очередь. Например:
(cl-incf (multisession-value foo-bar))
Сначала проверяется, изменилось ли значение в другой инстанции Emacs, извлекается это значение, а затем к нему прибавляется 1 и оно сохраняется. Но обратите внимание, что это делается без блокировки, поэтому, если многие инстанции обновляют значение одновременно, непредсказуемо, какая инстанция «победит».
Эта функция удаляет object и его значение из постоянного хранилища.
Вы также можете создавать постоянные значения, которые не привязаны к определенной переменной, но привязаны к явному пакету и ключу.
(setq foo (make-multisession :package "mail"
:key "friends"))
(setf (multisession-value foo) 'everybody)
Это поддерживает те же именованные аргументы, что и define-multisession-variable, но также поддерживает именованный аргумент :initial-value, который указывает значение по умолчанию.
Эта переменная контролирует, как хранятся переменные нескольких сессий. По умолчанию она установлена в files, что означает, что значения хранятся в структуре «один файл на переменную» внутри каталога, указанного в multisession-directory. Если же это значение установлено в sqlite, значения хранятся в базе данных SQLite; это возможно только в том случае, если Emacs был собран с поддержкой SQLite.
Переменные нескольких сессий хранятся в этом каталоге, который по умолчанию является подкаталогом multisession/ в user-emacs-directory, который обычно равен ~/.emacs.d/multisession/.
Эта команда выводит буфер со списком всех переменных нескольких сессий и входит в специальный режим multisession-edit-mode, который позволяет удалять их и редактировать их значения.