一直比较喜欢使用自动保存的方案,关于自动保存,这个帖子" 总结了一下自动保存的姿势 " 有一些讨论。
目前自动保存的方案中比较流行的有以下方案:
- 内置的
auto-save-visited-mode
,这个方案直接保存修改到正在编辑的文件,不会生成其他文件。
个人比较喜欢这个方案,但保存时都会在回显区(acho area) 中提示保存的消息。在 Emacs 28 版本,可以通过设置 (setq save-silently t) 进行解决。但是 Emacs 29 以后,由于在macOS 上关于显示方面的代码改动,产生了副作用,上面的设置就不生效了,保存时仍然会看到回显区闪一下。
对于这个问题,目前的临时解决方案是过滤掉 “Saving" 开头和 “Wrote” 开头的字符串:
(setq inhibit-message-regexps '("^Saving" "^Wrote"))
(setq set-message-functions '(inhibit-message))
这个问题我也提了 Bug,但 Eli 表示目前并不会去修复
https://lists.gnu.org/archive/html/bug-gnu-emacs/2023-03/msg01974.html
下面是个人目前使用的 auto-save-visited-mode
配置:
(use-package emacs
:custom
(auto-save-default nil)
(create-lockfiles nil)
(make-backup-files nil)
(inhibit-message-regexps '("^Saving" "^Wrote"))
(set-message-functions '(inhibit-message))
(auto-save-visited-interval 1)
(auto-save-visited-predicate
(lambda () (and (not (buffer-live-p (get-buffer " *vundo tree*")))
(not (string-suffix-p "gpg" (file-name-extension (buffer-name)) t))
(not (eq (buffer-base-buffer (get-buffer (concat "CAPTURE-" (buffer-name))))
(current-buffer)))
(or (not (boundp 'corfu--total)) (zerop corfu--total))
(or (not (boundp 'yas--active-snippets)) (not yas--active-snippets)))))
:hook (after-init . auto-save-visited-mode))
-
通过 auto-save 包,这是本论坛懒猫大佬的包,很好用,效果同 auto-save-visited-mode
,并且默认已经加了很多实用的predicate,还支持自动删除尾行空格。这也是我之前一直在用的包,切换到 auto-save-visited-mode
,其实就是为了尝试下内置包。
在功能上 auto-save.el 和 auto-save-visited-mode 策略都是定时保存全部应该保存的 buffer。
-
通过 super-save 这个包自动保存,这个包的方案比较温和,只保存当前的buffer,而且只在一些指定的事件中会触发保存(比如切换buffer,切换窗口,失去焦点等)。当然这个包也可以设置成定时保存。
-
内置的 auto-save-mode
, 默认开启,可以通过 (setq auto-save-default nil)
关闭
这个方案是将修改自动保存到当前目录下的以 # 开头和结尾的同名文件,比如 #foo.txt#
。 如果编辑文件是放在云盘的时候,这个文件也会被同步到云盘,就比较烦人了。
这个方案严格来说,不叫自动保存,应该是自动备份,因为修改完成后,还需要手动保存(C-x, C-s) 进行持久化保存。
3 个赞
其实auto-save-mode就挺不错的?已经不会丢东西了,在c-x c-c的时候,它问你是否保存的时候点一下y就好了。而且这样子还有在大量误操作的时候轻松回滚的好处
auto-save 配合 git 最好用, Emacs默认保存到其他文件的策略经常污染文件系统, 操作很不方便。
auto-save-mode 是不错的,即使 emacs 进程被意外 kill 了,重启 Emacs 后,仍然可以通过 M-x recover-this-file
恢复没保存的文件内容。确实不会造成文件丢失了。
我最近也在尝试用回默认的 auto-save-mode
,大部分情况都是很好用的。但在 Windows 系统上,如果我编辑的文件是 symlink 到 iCloud 下的文件时,如果按 C-x,C-s 保存文件,iCloud 就会弹窗提示我是否要将文件移动到本地,如果移动了,云盘上的文件就丢失了。这个问题请问下有没办法解决?
1 个赞
auto-save 确实是最省事的。使用 Git,编辑好重要的部分就commit一下。编辑期间也可以通过 vundo 进行可视化的 undo/redo。
我目前遇到的唯一不适合用 auto-save 的场景是:
在写 React 前端项目时,我是习惯开着 yarn start
来保持浏览器刷新的。如果 auto-save 开着的话,相当于一直在触发浏览器更新,有时会造成 CPU 疯狂转。这种情况下我会选择关闭自动保存。
其实可以写一个 predicate, 当遇到 React 文件的时候, 采取两个措施:
- 降低这种Web文件自动保存的频率
- 离开Emacs窗口马上保存一下
其实还是期望自动保存的, 只是不要频率那么高。
2 个赞
有道理,降低频率的方案感觉不错,有空再试试看。
其实内置 auto-save-mode 在处理长文件的时候就是使用你说的这个策略, 默认的 auto-save-timeout 是 30 秒,但是在编辑长文件时,实际的超时时间会更长一些。参考 Emacs 文档 Auto-Save-Control
时长应该跟场景有关系, 比如 npm run server 这种, 不应该和文件大小有关系, 在本地磁盘保存上, 多大文件都是瞬间保存。
1 个赞
我也是 Macos 我是用:
(defun save-buffer-silently ()
"Save the buffer silently."
(interactive)
(let ((inhibit-message t)) ; temporarily disable message display
(save-buffer)))
来保存的,这样就不会在 echo 区域输出保存的信息。因为我用的是 emacs-29 最新的分支,有些时候会闪退,所以我就加了一个 idle timer 来自动保存,每次保存的时候有提示的确会干扰思路
抄了這段代碼,發現也沒辦法做到「自動保存不要刪除空格」。
貓大的 auto-save,設置了[ (setq auto-save-delete-trailing-whitespace nil)
],也是會自動刪除空格。
mac下升級了emacs 29 之後,沒想到問題這麼多。
你抄了哪段代码?猫哥的 auto-save.el 不需要这些配置,默认已经支持了。我的这些配置是针对Emacs内置的 auto-save-visited-mode
的。
你说的是什么情况下会自动刪除空格?可以贴下你的 auto-save 配置,看看能否重现。
(use-package emacs
:custom
(auto-save-default nil)
(create-lockfiles nil)
(make-backup-files nil)
(inhibit-message-regexps '("^Saving" "^Wrote"))
(set-message-functions '(inhibit-message))
(auto-save-visited-interval 1)
(auto-save-visited-predicate
(lambda () (and (not (buffer-live-p (get-buffer " *vundo tree*")))
(not (string-suffix-p "gpg" (file-name-extension (buffer-name)) t))
(not (eq (buffer-base-buffer (get-buffer (concat "CAPTURE-" (buffer-name))))
(current-buffer)))
(or (not (boundp 'corfu--total)) (zerop corfu--total))
(or (not (boundp 'yas--active-snippets)) (not yas--active-snippets)))))
:hook (after-init . auto-save-visited-mode))
抄的這段,與貓大的一樣也是自動刪除空格,如何設置不自動刪除,或者當前行不刪除空格。
貓大的auto-save,我是這樣設置的
;;(load! "auto-save")
;;
;; (add-to-list 'load-path (expand-file-name "~/.config/doom/auto-save"))
;; (require 'auto-save)
;; (setq auto-save-idle 15)
;; (auto-save-enable)
;; (setq auto-save-silent t) ; quietly save
;; (setq auto-save-delete-trailing-whitespace nil)
auto-save.el 默认就是关闭自动删除尾行空格功能的。你不必设置 auto-save-delete-trailing-whitespace 为 nil,不过你设置了也不会有什么坏处。
我的那段配置只是启用了 auto-save-visited-mode 进行自动保存,没有设置删除空格。
你用的是 doom 的配置?可能是你启用了其他自动删除尾行空格的包,所以在自动的保存的时候给你清除了空格。
我是使用 ws-butler 这个包进行删除空格,它不会影响当前行,因为它会用虚空格填补被删除的空格。
是的,應該是這個問題,之前沒有啟用auto-save包,所以沒察覺自動刪除行尾空格的情況。查看配置,大概只有 save-buffer,一個命令。
Emacs 29.1 在 Macos 上设置 save-silently 为 t 后,回显区己经不闪 (是因为我把mode-line 关掉使用了 echo-bar 插件)
己经可以从 auto-save 转到使用 auto-save-visited-mode 了。
对于 capture 时自动删空格的问题从 auto-save 中抄了下面这个函数,把 capture buffer 对应的文件忽略掉。暂时可用。如果能把 “CAPTURE-”对应的文件都忽略就更好了。
(defun auto-save-delete-trailing-whitespace-except-current-line ()
(interactive)
(when (not (string-prefix-p "inbox" (buffer-name (buffer-base-buffer))))
(let ((begin (line-beginning-position))
(end (point)))
(save-excursion
(when (< (point-min) begin)
(save-restriction
(narrow-to-region (point-min) (1- begin))
(delete-trailing-whitespace)))
(when (> (point-max) end)
(save-restriction
(narrow-to-region end (point-max))
(delete-trailing-whitespace))))))))
哪个 commit 修复这个问题了?我用的 最新的 Emacs 30 都还是会闪。还是要用开始提到的临时方案。
我修改了。
我改用 auto-save-visited-mode 时用的是 echo-bar 没有使用 mode-line ,把 mode-line 调回来之后又闪了。。。。。。