我使用Emacs(目前是26.3)已经有一段时间了(几年)。我总是有
(use-package saveplace
:config
(save-place-mode t))
在我 init.el
,这使得Emacs使用 save-place-mode
(这是与vanilla Emacs一起出现的,作为 saveplace.el
),以便记住文件中的最后一个位置。
我的问题 存放处 是,它一直将访问过的文件和位置保存到一个名为 save-place-alist
钩 kill-emacs-hook
它将这个列表转储到默认位置 ~/.emacs.d/places
. 但它经常发生,我忘记或以某种方式不正常退出我的emacs-daemon。所以,这个列表会丢失。
我的方法是提取函数 save-place-alist-to-file
从 saveplace.el
并将其加入 kill-buffer-hook
所以现在,每当我杀死一个缓冲区的时候。save-place-alist
会被保存到磁盘上。这就是我现在的保存位置配置。
(defun my-save-place-alist-to-file ()
(interactive)
(save-place-to-alist)
(let ((file (expand-file-name save-place-file))
(coding-system-for-write 'utf-8))
(with-current-buffer (get-buffer-create " *Saved Places*")
(delete-region (point-min) (point-max))
(when save-place-forget-unreadable-files
(save-place-forget-unreadable-files))
(insert (format ";;; -*- coding: %s -*-\n"
(symbol-name coding-system-for-write)))
(let ((print-length nil)
(print-level nil))
(pp save-place-alist (current-buffer)))
(let ((version-control
(cond
((null save-place-version-control) nil)
((eq 'never save-place-version-control) 'never)
((eq 'nospecial save-place-version-control) version-control)
(t
t))))
(condition-case nil
;; Don't use write-file; we don't want this buffer to visit it.
(write-region (point-min) (point-max) file)
(file-error (message "Saving places: can't write %s" file)))
(kill-buffer (current-buffer))))))
(use-package saveplace
:config
(save-place-mode t)
;; (remove-hook 'kill-buffer-hook 'save-place-to-alist)
;; (add-hook 'kill-buffer-hook 'my-save-place-alist-to-file))
一切都很好,只要我不修改我的文件 kill-buffer-hook
通过取消最后一行的注释。函数 my-save-place-alist-to-file
当交互式调用时,工作正常。但是当激活钩子的时候,几乎所有的东西都会刹车。首先,我不能再杀死缓冲区了。我得到了这个与递归深度有关的错误。
progn: Variable binding depth exceeds max-specpdl-size
调试器说:
Debugger entered--Lisp error: (error "Variable binding depth exceeds max-specpdl-size")
generate-new-buffer(" *temp*")
pp-to-string((("/home/.../test.txt" . 33)))
pp((("/home/.../test.txt" . 33)) #<buffer *Saved Places*>)
(let ((print-length nil) (print-level nil)) (pp save-place-alist (current-buffer)))
(save-current-buffer (set-buffer (get-buffer-create " *Saved Places*")) (delete-region (point-min) (point-max)) (if save-place-forget-unreadable-files (progn (save-place-forget-unreadable-files))) (insert (format ";;; -*- coding: %s -*-\n" (symbol-name coding-system-for-write))) (let ((print-length nil) (print-level nil)) (pp save-place-alist (current-buffer))) (let ((version-control (cond ((null save-place-version-control) nil) ((eq (quote never) save-place-version-control) (quote never)) ((eq (quote nospecial) save-place-version-control) version-control) (t t)))) (condition-case nil (write-region (point-min) (point-max) file) (file-error (message "Saving places: can't write %s" file))) (kill-buffer (current-buffer))))
(let ((file (expand-file-name save-place-file)) (coding-system-for-write (quote utf-8))) (save-current-buffer (set-buffer (get-buffer-create " *Saved Places*")) (delete-region (point-min) (point-max)) (if save-place-forget-unreadable-files (progn (save-place-forget-unreadable-files))) (insert (format ";;; -*- coding: %s -*-\n" (symbol-name coding-system-for-write))) (let ((print-length nil) (print-level nil)) (pp save-place-alist (current-buffer))) (let ((version-control (cond ((null save-place-version-control) nil) ((eq ... save-place-version-control) (quote never)) ((eq ... save-place-version-control) version-control) (t t)))) (condition-case nil (write-region (point-min) (point-max) file) (file-error (message "Saving places: can't write %s" file))) (kill-buffer (current-buffer)))))
my-save-place-alist-to-file()
kill-buffer(#<buffer *temp*-840370>)
#f(compiled-function () #<bytecode 0x1c65c75>)()
pp-to-string((("/home/.../test.txt" . 33)))
pp((("/home/.../test.txt" . 33)) #<buffer *Saved Places*>)
(let ((print-length nil) (print-level nil)) (pp save-place-alist (current-buffer)))
(save-current-buffer (set-buffer (get-buffer-create " *Saved Places*")) (delete-region (point-min) (point-max)) (if save-place-forget-unreadable-files (progn (save-place-forget-unreadable-files))) (insert (format ";;; -*- coding: %s -*-\n" (symbol-name coding-system-for-write))) (let ((print-length nil) (print-level nil)) (pp save-place-alist (current-buffer))) (let ((version-control (cond ((null save-place-version-control) nil) ((eq (quote never) save-place-version-control) (quote never)) ((eq (quote nospecial) save-place-version-control) version-control) (t t)))) (condition-case nil (write-region (point-min) (point-max) file) (file-error (message "Saving places: can't write %s" file))) (kill-buffer (current-buffer))))
(let ((file (expand-file-name save-place-file)) (coding-system-for-write (quote utf-8))) (save-current-buffer (set-buffer (get-buffer-create " *Saved Places*")) (delete-region (point-min) (point-max)) (if save-place-forget-unreadable-files (progn (save-place-forget-unreadable-files))) (insert (format ";;; -*- coding: %s -*-\n" (symbol-name coding-system-for-write))) (let ((print-length nil) (print-level nil)) (pp save-place-alist (current-buffer))) (let ((version-control (cond ((null save-place-version-control) nil) ((eq ... save-place-version-control) (quote never)) ((eq ... save-place-version-control) version-control) (t t)))) (condition-case nil (write-region (point-min) (point-max) file) (file-error (message "Saving places: can't write %s" file))) (kill-buffer (current-buffer)))))
my-save-place-alist-to-file()
kill-buffer(#<buffer *temp*-437350>)
#f(compiled-function () #<bytecode 0x1c65c35>)()
pp-to-string((("/home/.../test.txt" . 33)))
pp((("/home/.../test.txt" . 33)) #<buffer *Saved Places*>)
(let ((print-length nil) (print-level nil)) (pp save-place-alist (current-buffer)))
(save-current-buffer (set-buffer (get-buffer-create " *Saved Places*")) (delete-region (point-min) (point-max)) (if save-place-forget-unreadable-files (progn (save-place-forget-unreadable-files))) (insert (format ";;; -*- coding: %s -*-\n" (symbol-name coding-system-for-write))) (let ((print-length nil) (print-level nil)) (pp save-place-alist (current-buffer))) (let ((version-control (cond ((null save-place-version-control) nil) ((eq (quote never) save-place-version-control) (quote never)) ((eq (quote nospecial) save-place-version-control) version-control) (t t)))) (condition-case nil (write-region (point-min) (point-max) file) (file-error (message "Saving places: can't write %s" file))) (kill-buffer (current-buffer))))
(let ((file (expand-file-name save-place-file)) (coding-system-for-write (quote utf-8))) (save-current-buffer (set-buffer (get-buffer-create " *Saved Places*")) (delete-region (point-min) (point-max)) (if save-place-forget-unreadable-files (progn (save-place-forget-unreadable-files))) (insert (format ";;; -*- coding: %s -*-\n" (symbol-name coding-system-for-write))) (let ((print-length nil) (print-level nil)) (pp save-place-alist (current-buffer))) (let ((version-control (cond ((null save-place-version-control) nil) ((eq ... save-place-version-control) (quote never)) ((eq ... save-place-version-control) version-control) (t t)))) (condition-case nil (write-region (point-min) (point-max) file) (file-error (message "Saving places: can't write %s" file))) (kill-buffer (current-buffer)))))
my-save-place-alist-to-file()
...
我已经尝试了很多方法来解决这个问题. 我的第一个猜测是,最后调用的 (kill-buffer (current-buffer))
会导致无限递归。但去掉它也无济于事。
总结一下,我的问题是: * 为什么会发生无限递归?* 为什么会发生无限递归?
我尝试了 @choroba 提到的,在我的init.el中添加了一个 "save-place-mode t"。
(let 'kill-buffer-hook nil
...
)
围绕整个部分后 (save-place-to-alist)
这确实消除了无限递归的问题!但后来又出现了另一个问题:每当我切换缓冲区时,这个hooked都会被调用。但后来又出现了另一个问题:每当我切换缓冲区时,这个hooked都会被调用,which-key上下跳动,而且在很多场合都会被调用。每次写到 ~/.emacs.d/places
. 所以这不是我想要的。
同时,我找到了一个方便的解决方案:添加函数 不 至 kill-buffer-hook
不过 到 after-save-hook
. 这对我来说已经足够了:)
我的最后 save-place
-设置对我来说很好,现在看起来是这样的。
(defun my-save-place-alist-to-file ()
(interactive)
(save-place-to-alist)
(let ((file (expand-file-name save-place-file))
(coding-system-for-write 'utf-8))
(with-current-buffer (get-buffer-create " *Saved Places*")
(delete-region (point-min) (point-max))
(when save-place-forget-unreadable-files
(save-place-forget-unreadable-files))
(insert (format ";;; -*- coding: %s -*-\n"
(symbol-name coding-system-for-write)))
(let ((print-length nil)
(print-level nil))
(pp save-place-alist (current-buffer)))
(let ((version-control
(cond
((null save-place-version-control) nil)
((eq 'never save-place-version-control) 'never)
((eq 'nospecial save-place-version-control) version-control)
(t
t))))
(condition-case nil
;; Don't use write-file; we don't want this buffer to visit it.
(write-region (point-min) (point-max) file nil) ; 4th arg nil means: do not append!
(file-error (message "Saving places: can't write %s" file))
(kill-buffer (current-buffer)))))))
(use-package saveplace
:config
(save-place-mode t)
(add-hook 'after-save-hook 'my-save-place-alist-to-file)) ; after-save-hook seems to be the best place for this