Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Idiomatic way serialization in emacs lisp

Tags:

emacs

lisp

elisp

Currently I am working on a elisp major mode that makes uses of hashtables across sessions. So every time the major mode is initialized, the tables are loaded into memory. During and at the end of the session they are written to a file. My current implementation writes the data in the following way:

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

Loading the data at the beginning of the session is done via read and is something like this:

(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))))))))

It works but I have the feeling that this is not the most beautiful way to do it. My aim is: I want this major mode to turn into a nice clean package that stores it's own data in the folder where the other data of the package is stored.

like image 720
Sebastian_學生 Avatar asked Mar 24 '16 05:03

Sebastian_學生


3 Answers

This is how I implement

Write to file:

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

Read from file:

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

Call to write:

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

Call to read

(my-read "~/test.txt" 'my-emacs-version)
like image 70
tom Avatar answered Oct 17 '22 18:10

tom


I came up with the following solution, inspired by the first answer here:

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

And during the init of the major mode, I just do:

(load "my-data-lib")

No need for and read-operation and the plus is that I also don't need to give any filepath, just the fact that there is such a file somewhere on the load-path is enough. Emacs will find it. elisp rocks. :)

like image 29
Sebastian_學生 Avatar answered Oct 17 '22 19:10

Sebastian_學生


The package desktop can do it for you:

(require 'desktop)
(unless (memq 'hash-table desktop-globals-to-save)
  (nconc desktop-globals-to-save (list 'hash-table)))` 
like image 2
duthen Avatar answered Oct 17 '22 18:10

duthen