我想把一个变量存在文件中。重启时再从文件中读取。
我是这样存的:
;;; save variable `ivy-views' to file, it will overide the file
(with-temp-file "/tmp/elisp.el"
(insert (format "%s" ivy-views)))
这样读出来:
(with-temp-buffer
(insert-file-contents "/tmp/elisp.el")
(goto-char (point-min))
(read (current-buffer)))
但是我发现读出来内容里面原来的 . 号前面都加了一个 \,变成了 \. 。
我发现问题出在read这个函数上。比如下面这段:
(read "(haha nihao.py)")
我期待是返回这样的一个list:
(haha nihao.py)
结果回来的是:
(haha nihao\.py)
请问有人知道这是什么原因吗?有没有什么办法可以实现我的目标?谢谢
(format "%s" ...)
即 princ
产生的是让人容易理解的结果,比如一个 Buffer 对象返回的它的名字、一个字符串返回的是它的内容(没有 Quote 了),所以 read
也不能处理它的结果。
或者 pp
之类(即 prin1
)都行,它们产生的结果 read
能处理。
不过应该有专门处理这个需求的包,另外,像 Emacs 自带的 savehist-mode
或者 desktop-save-mode
,如果用的话,可以直接用它们来存储,估计分别像这样:
(setq savehist-additional-variables '(ivy-views))
(add-to-list 'desktop-globals-to-save 'ivy-views)
1 个赞
谢谢。
因为我把变量存入文件后再读出来是带引号的字符串。而变量的值实际是和该字符串对应的lisp对象。我觉得它应该就是一个list。所以我觉得我应该找到从字符串转到list的方法。
然后我想到了bookmark是可以持久化的,所以我去看了下它的代码。它大概是用:
(read (current-buffer))
这样的形式来读的。而read我看也支持string。所以就试了:
(read "(haha nihao.py)")
发现结果会多出一个 \ 。感觉就差最后一步了。
我试了下面这些:
#+BEGIN_SRC elisp
(read "(haha nihao.py)")
(read (format "%S" "(haha nihao.py)"))
(read (format "%s" "(haha nihao.py)"))
(read (prin1 "(haha nihao.py)"))
(read (pp "(haha nihao.py)"))
(format "%S" (read "(haha nihao.py)"))
(read (prin1 "xiepeng.py"))
(read (princ "xiepeng.py"))
#+END_SRC
但是都没达到我的目的。
desktop-save-mode我一般没开。savehist-mode还没有用过。
谢谢二呆。我其实就是想把字符串转为list。不过这个我应该怎么用呢?
(read (format "%S" "(haha nihao.py)"))
(read (format "%s" "(haha nihao.py)"))
第一种出来还是一个字符串。第二种出来还是有 \ 。
Execute a file of Lisp code named FILE.
查了下help。它应该是执行一个文件中的elisp代码。
Costume variable 就是向文件写入一个做 setq
的表达式,读取的时候就用 load,执行表达式,就可以直接用绑定的变量名调用数据了。还有个 Emacs rouge like 游戏就是这样保存数据的。如果不想要副作用,你可以看看 load 是不是有返回值。
除非对保存数据的文件格式有特别要求,比如必须要 YAML 格式又要用 Emacs 读取。
谢谢。不过我对custom不是太熟。不知道我是应该直接 M-x customize然后找到变量save呢?还是有对应的elisp函数?我试了下:
(custom-variable-save 'ivy-views)
(custom-variable-set 'ivy-views)
(custom-variable-backup-value 'ivy-views)
都有错。不好意思elisp比较菜。
LdBeth
10
Custom 要用 defcustom
定义变量。这样才能在自定义面板被找到。
我只是举个例子。一般自定义部分之间写配置机酒可以了。
我用类似的方法管理 elpa 镜像
init.el
(defun expand-file (file)
"Expand FILE content in place."
(read-from-whole-string
(with-temp-buffer
(insert-file-contents file)
(buffer-string))))
~/.elpa.el
(("gnu" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")
("melpa" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")
("melpa-Stable" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa-stable/")
("marmalade" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/marmalade/")
("org" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/org/"))
展开文件内容到变量
(setq elpas `',(expand-file "~/.elpa.el"))
谢谢。但是我这样读出来还是有 \ 。
/tmp/elisp.el中的内容是这样的:
(({} *Help* Upgrade.py (vert (file /Users/pengpengxp/src/asp/build/Upgrade.py 16481) (buffer *Help* 1))) ({} *Help* *scratch* (vert (buffer *scratch* 304) (buffer *Help* 1))))
这样读出来的Upgrade.py前面还是有个 \ 。难道是我环境的问题?
你这个文件的写法不对,该引号的加引号,该 quote 的 quote,就跟普通的 .el 文件一样写
这个文件我是这样直接把变量写入的:
(with-temp-file "/tmp/elisp.el"
(insert (format "%s" ivy-views)))
你应该不需要管 Lisp 对象和文件(字符串)之间的转换,那是 prin1
和 read
的事情。可以试试:
ivy-views
=> (("{} *scratch*" (buffer "*scratch*" 1)))
(with-temp-file "/tmp/foo.el"
(prin1 ivy-views (current-buffer)))
(equal ivy-views
(with-temp-buffer
(insert-file-contents "/tmp/foo.el")
(read (current-buffer))))
=> t
~ $ cat /tmp/foo.el
(("{} *scratch*" (buffer "*scratch*" 1)))
2 个赞
format 之后当然一切都变了,楼上是 prin1 的写法正解。或者前面提到的 defcustom:
(defcustom foo nil
"Blablabla..."
:group 'test
:type 'alist)
然后持久化写入到 custom.el:
(customize-save-variable 'foo '("bar" . 123))
下次 emacs 启动加载 custom.el, 读取 foo 的值
1 个赞
(read (format “%S” '(haha nihao.py))) 一般是这麽用吧?
明白了。其实我就是有时候想把ivy-views存起来,重启后可以恢复。非常感谢。