emacs的auto-revert不够及时导致的问题

在mac上遇到的, linux最近没怎么用.

最近遇到好几次: 一个git仓库, 很多文件用emacs打开, 并全部保存. 然后在命令行来回切换分支, 偶尔emacs里面某个文件会处于修改状态, 且文件内容会部分缺失. 估计是revert的半途中, 又切换了分支, 文件又改变了.

一方面revert的时候切换分支会有冲突, 这个可以理解. 另一方面, 切换分支是手工用命令行操作的, 速度不会很快, 两次间隔四五秒以上, emacs的文件改变检测不够及时, 不能及时地revert. 后者是主要原因.

印象中linux版本的revert也有明显的延迟.

还有一个问题, emacs打开的文件, 用命令行将文件删除, emacs竟然什么也不提示, 简直是功能缺失啊.

然而并没有什么解决的办法。

能有 auto revert 已经不错了,别的编辑器连这功能都没有。唯一一个能完全实时映射对文件操作的编辑器也就 acme,还需要 Plan9 的 9P FS 支持。

连 Pages 都没有这功能,叫啥功能性缺失?


如果你用 Magit 在 Emacs 里面调用 git 的话,它倒是会给你处理好。

我配置的一部分:

;;; Auto-refresh buffers when files have changed on disk
(global-auto-revert-mode t)

文档:

2 个赞

在Emacs 里面,buffer 是文件的一个"copy",当你重新写入到文件之前,这个副本和原来的文件是没有关系的.因为你从命令行删除这个文件,而不是从类似dired里面删除文件的,所以在你保存buffer 到文件之前,Emacs 是不会感知你文件的存在与否的.所以我觉得这并不是一个功能缺失,而是一个合理的功能.当你保存这个 buffer 的时候,提示你的文件不存在才是合理的.

1 个赞

当你觉得自己遇到一个了 Bug 时,就报告一个 Bug,Feature Request 也算作 Bug 的一种。因为如果真是 Bug 的话,发到这里来也不会得到解决。

目前主流操作系统都有文件变化通知,基本没有延迟,有一个fswatch的开源工具可以试验,只能说emacs还没做好,印象中linux上emacs检测文件变更也有延迟,不知道怎么回事

这个是打开的,就是不够及时,有两三秒左右的延迟

然而文件变更是有auto revert的,说明并没有分离,而文件删除就是特殊的变更。感觉是挺基本的功能,特别是对于emacs这种堪称os的东西

交流一下看有什么自己没意识到的,看别人是怎么用的。英文交流太困难了,不太擅长

这个实现的原理是开一个计时进程定时检查文件,Emacs 速度并不快,自然会有比较明显的 lag。除非文件系统层面就支持,不然或多或少都会有一个检查文件间隔的延迟。

不能用用户自己的母语报告 Bug 确实非常不友好,我相信这妨碍了很多人报告 Bug,但目前也只能用英文。报告 Bug 对英文水平要求一点儿都不高,因为其格式很固定,以 Bug#29812 为例:

27.0.50; electric-quote-replace-double misbehaves in Lisp strings

To reproduce:

  emacs -Q
  M-x electric-quote-mode RET
  M-x set-variable RET electric-quote-replace-double RET t RET

Type:

  "foo \"foo\""

You get this in the buffer:

  "foo \”foo\”"

I expected "foo \“foo\”" instead.


In GNU Emacs 27.0.50 (build 56, i686-pc-mingw32)
....

它包括了:

  • 重现步骤
  • 预期结果
  • 实际结果
  • 版本信息

这应该比 100 字的英文写作题简单得多,因此除非你完全不会英文,否则你应该尝试报告 Bug 的。

或许你可以在 Reddit 的 Emacs 版区上面去提这个问题,我一般有问题解决不了都会在Reddit 上面提问的,因为上面会有 Evil maintainer, GNU Emacs maintainer 这样的大佬出来回答问题。之前我也提过一个问题,不知道是不是bug, 所以在报 bug 之前,我先去了 Reddit 版区发帖问了一下,最后 eli-zaretskii(现在维护Emacs 的大佬)帮我解决了。BTW, Emacs 社区是我见过最友好的社区之一(另外一个是 Rust社区),所以只管去提问 :)

前提是,你要把问题说明白,不然大家也没法帮你。

可能是因为 emacs 一直是小众的工具,所以社区就没有那种浮躁的东西。。。。

1 个赞

主流os本来就支持啊, fswatch就是用的各自系统原生的通知接口, 所以没有延迟. 因为文件操作都是通过os进行的, 所以并不依赖于底层的文件系统(可能网络文件系统会比较特殊, 有延迟). 定时器检测是最下下选择, 只是作为备选.

我看26里面刚加了一个功能, 检测文件变化不再基于文件修改时间戳, 而是基于文件的真实内容, 好像是用于版本管理时checkout了其他分支, 然后又checkout回来的情况, 此时文件时间戳变了, 但是文件内容没变.

这功能都加了, 就是不改进auto-revert的及时性. 加了这功能, 还会考虑auto-revert的及时性吗? 这个功能好像就是基于auto-revert不及时. 如果及时的话, 新加这个功能意义不大了.

很早以前看到过相关讨论, 就是auto-revert的检测问题, 对freebsd和mac支持得不好, 这两个系统提供了一套原生的文件变更通知接口, 但是该接口对每一个文件会耗费一个文件句柄, 还有其他一些限制. 而mac又提供了另外一套接口, 性能和可靠性都不错, 当时emacs还不支持, 到现在好像没什么进展

如果 fswatch 已经能满足你的需求的话,倒也应该可以通过改写把 fswatch 作为 auto revert 的后端。

不用 auto-revert,也不是 Mac 平台。

看了下源码,是用 file-notify-add-watch 实现的。 文档见 38.20 Notifications on File Changes, 好像没有提供 delete 的 FLAG, 也许可以用 EVENT 提供的 deleted ACTION 来实现。

改动函数 auto-revert-notify-handler,添加 'deleted 条件并显示信息。 试了一下,在 Windows 平台下暂时是有效的,不清楚其它平台。

2 个赞

不同平台用的 file watcher 后端是不一样的。