首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Emacs保存保存位置-保存文件时,杀死缓冲区:为什么我得到递归深度问题与钩子?

Emacs保存保存位置-保存文件时,杀死缓冲区:为什么我得到递归深度问题与钩子?
EN

Stack Overflow用户
提问于 2020-04-28 09:54:24
回答 1查看 168关注 0票数 0

我已经使用Emacs (目前为26.3)相当一段时间(数年)。我一直都有

代码语言:javascript
复制
(use-package saveplace
  :config
  (save-place-mode t))

在我的init.el中,Emacs使用save-place-mode (它附带香草Emacs作为saveplace.el)来记住文件中的最后一个位置。

我对saveplace的问题是,它一直将已访问的文件和位置保存到一个名为save-place-alist的列表中,并且只通过kill-emacs-hook中的一个钩子将该列表转储到默认位置~/.emacs.d/places。但这种情况经常发生,我忘记了,或者通常不会退出我的emacs守护进程。所以名单就会丢了。

我的方法是从save-place-alist-to-file中提取函数saveplace.el并将其添加到kill-buffer-hook中,因此现在,每当我杀死缓冲区save-place-alist时,都会将其保存到磁盘中。这就是我的保存位置配置现在看起来的样子:

代码语言:javascript
复制
(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在交互调用时正常工作。但当启动钩子时,几乎所有的东西都会刹车。首先,我不能再杀死缓冲区了。我得到了与递归深度相关的错误:

代码语言:javascript
复制
progn: Variable binding depth exceeds max-specpdl-size

调试器说:

代码语言:javascript
复制
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))的最后调用将导致无限递归。但是移除它没有帮助。

总之,我的问题是:

*无限递归发生的原因和地点?

EN

回答 1

Stack Overflow用户

发布于 2020-04-29 11:12:33

我尝试了@choroba通过添加一个

代码语言:javascript
复制
(let 'kill-buffer-hook nil
...
) 

围绕(save-place-to-alist)之后的整个部分,确实消除了无限递归问题!但随后又出现了另一个问题:每当我切换缓冲区时,这个钩子就会被叫来,而这个键在更多的情况下都会弹出。每次写信给~/.emacs.d/places。所以这不是我想要的。

同时,我找到了一个方便的解决方案:不是将函数添加到kill-buffer-hook,而是将函数添加到after-save-hook。对我来说就足够了:)

我的最后一个save-place-setup (对我来说很好)现在看起来如下:

代码语言:javascript
复制
(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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61477406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档