2016-03-24 2 views
3

В настоящее время я работаю над основным режимом elisp, который использует использование хэш-таблиц на всех сеансах. Поэтому каждый раз, когда основной режим инициализируется, таблицы загружаются в память. Во время и в конце сеанса они записываются в файл. Моя текущая реализация записывает данные следующим образом:Идиоматическая сериализация пути в emacs lisp

(with-temp-buffer 
    (prin1 hash-table (current-buffer)) 
    (write-file ("path/to/file.el")))) 

Загрузка данных в начале сессии осуществляется с помощью чтения и что-то вроде этого:

(setq name-of-table (car 
     (read-from-string 
     (with-temp-buffer 
      (insert-file-contents path-of-file) 
      (buffer-substring-no-properties 
     (point-min) 
     (point-max)))))))) 

Это работает, но у меня есть чувствуя, что это не самый красивый способ сделать это. Моя цель: я хочу, чтобы этот главный режим превратился в хороший чистый пакет, в котором хранятся его собственные данные в папке, где хранятся другие данные пакета.

+1

Поместите инициализатору в Lisp код, который вы оцениваете так или иначе? Сохраняет вас от выполнения каких-либо сложных материалов при чтении - тогда вы можете просто «eval-buffer» и код, который вы добавляете, когда нужно писать, просто нужно быть '(setq variable' и закрывающий палец в конце. – tripleee

+0

выглядит просто и выполнимо. ^^ Я посмотрю, как это работает, и если это пройдет гладко, я пометю ваше сообщение как ответ. :) –

+0

Не нужно преобразовывать в строку, просто выполните '(read (current-buffer))' во временном буфере. – Lindydancer

ответ

2

Это, как я реализую

Записать в файл:

(defun my-write (file data) 
    (with-temp-file file 
    (prin1 data (current-buffer)))) 

Чтение из файла:

(defun my-read (file symbol) 
    (when (boundp symbol) 
    (with-temp-buffer 
     (insert-file-contents file) 
     (goto-char (point-min)) 
     (set symbol (read (current-buffer)))))) 

Позвоните, чтобы написать:

(my-write "~/test.txt" emacs-version) 

вызова читать

(my-read "~/test.txt" 'my-emacs-version) 
+1

Вы можете использовать '(goto-char (point-min))', за которым следует '(read (current-buffer))', таким образом вам не нужно создавать строку. – Lindydancer

+0

@ Lindydancer Отредактировано с учетом вашего предложения. – tom

+0

Отлично! Тем не менее, я бы предложил поместить 'goto-char' сразу после' insert-file-content', таким образом, его будет легче читать. Кроме того, есть ли причина, по которой вы просто не возвращаете значение чтения вместо установки переменной? Этот код был бы очень прямым: '(defun my-read-from-file (file) (с-temp-buffer (файл-файл-файл-файл) (goto-char (point-min)) (read (current- buffer)))) ' – Lindydancer

1

я придумал следующее решение, вдохновленный первым ответом здесь:

(with-temp-buffer 
    (insert "(setq hash-table ") 
    (prin1 hash-table (current-buffer) 
    (insert ")") 
    (write-file (locate-library "my-data-lib")) 

А во время инициализации в основном режиме, я просто делаю:

(load "my-data-lib") 

Нет необходимости for и read-operation и плюс - это то, что мне также не нужно указывать какой-либо путь к файлу, достаточно факта, что есть такой файл где-то на пути загрузки. Emacs найдет его. elisp пород. :)

1

Пакет desktop может сделать это для вас:

(require 'desktop) 
(unless (memq 'hash-table desktop-globals-to-save) 
    (nconc desktop-globals-to-save (list 'hash-table)))`