我在尝试设置一些保存一些持久状态的东西时遇到了一些困难,以便我可以在 emacs 调用之间使用数据。
使用来自另一个问题的一些代码作为起点,我想出了以下小代码片段来做我想做的事情:
(defmacro with-output-to-file (path &rest body)
"record output of commands in body to file"
`(save-excursion
(let* ((buf (find-file-noselect ,path))
(standard-output buf))
(set-buffer buf)
(erase-buffer)
,@body
(save-buffer)
(kill-buffer))))
然后我有一个使用它的函数,例如:
(defun my-save-some-data ()
(with-output-to-file my-data-save-file
(prin1 my-data)))
编辑:这些都遵循如下代码(以前,这些都是 setq;感谢@phils 的评论启发我将它们切换到devfar
and defcustom
):
; note: my actual variable names (and filename value) are different;
; changed for example sake:
(defvar my-data (make-hash-table :test 'equal) "Data for a thing")
(defcustom my-data-save-file "~/tmp/my-data.el" "File to save my data to")
(注意:我还有一个功能可以读回数据,这会在加载时自动发生,或者按需发生。)
我已将其设置为在几种情况下运行(可能太多?可能选择不佳?无论如何,这就是我设置的):
(add-hook 'auto-save-hook 'my-save-some-data)
(add-hook 'kill-emacs-hook 'my-save-some-data)
(add-hook 'post-gc-hook 'my-save-some-data)
大多数情况下,这工作正常。但是,每隔一段时间,我就会遇到一个问题,即数据被写入我以前打开的缓冲区之一(在那里杀死所有以前的内容!),然后该缓冲区被杀死,保存的更改。
可以这么说,这非常烦人,因为发生这种情况的缓冲区经常在我一直在做一些工作的地方,但不一定要签入。
我尝试更改上面的宏,从(set-buffer buf)
on 替换为:
(with-current-buffer buf ; because set-buffer wasn't working??
(erase-buffer)
,@body
(if (eq buf (current-buffer))
(progn
(save-buffer)
(kill-buffer))
(message "buffer changed?!"))))))
这以某种方式设法使其附加到缓冲区,而不是覆盖它......所以我的 if 语句似乎在某种程度上工作......但是我在*Messages*
缓冲区中看不到消息,所以...... . 我不太确定发生了什么事。
我想我注意到的一件事(虽然很难确定,因为当这种情况发生时我可能不会积极关注)是这发生在一个非当前活动的缓冲区中,而不是我现在的缓冲区中目前正在编辑。
所以,问题:
- 我在这里做错了吗?
- 还有其他/更好的方法吗?
- 有没有我可以使用的以编程方式保存状态的标准方法?(我适当地四处寻找,但没有找到任何东西......虽然也许我只是不知道要寻找什么。)
- 我能做些什么来帮助自己追踪这个问题?(有没有办法可以设置断点或其他东西?)
- 我可以在这样的代码中使用其他保护措施吗?
欢迎任何其他想法。我正在添加更多(message)
表单,希望同时获得更多调试信息。
更新:我发现这只发生在post-gc-hook
. 我不知道我的变量是否以某种方式被破坏(也许切换到defvar
并defcustom
会解决这个问题?),或者在 gc-hook 后处理中是否存在某种晦涩的错误......检查重现测试用例有了这个最新的变化。