Emacs Lisp,如何监视文件/目录的更改

5

我正在寻找一种方法,定期检查某个目录下的文件是否与上次检查时有变化(类似于FAM守护程序或gio.monitor_directory的功能)。在emacs lisp中。

  • 是否有任何库/代码片段提供此功能?
  • 如果没有,如何实现这样的功能?
3个回答

6
(defun install-monitor (file secs)
  (run-with-timer
   0 secs
   (lambda (f p)
     (unless (< p (second (time-since (elt (file-attributes f) 5))))
       (message "File %s changed!" f)))
   file secs))

(defvar monitor-timer (install-monitor "/tmp" 5)
  "Check if /tmp is changed every 5s.")

取消操作:
(cancel-timer monitor-timer)

编辑:

如mankoff所述,上面的代码片段监视最近5秒钟内文件修改情况,而不是自上次检查以来。为了实现后者,我们需要每次检查时保存属性。希望这样可以解决问题:

(defvar monitor-attributes nil
  "Cached file attributes to be monitored.")

(defun install-monitor (file secs)
  (run-with-timer
   0 secs
   (lambda (f p)
     (let ((att (file-attributes f)))
       (unless (or (null monitor-attributes) (equalp monitor-attributes att))
         (message "File %s changed!" f))
       (setq monitor-attributes att)))
   file secs))

(defvar monitor-timer (install-monitor "/tmp" 5)
  "Check if /tmp is changed every 5s.")

1
这段代码有时候可以工作,但并不总是符合“自上次检查以来”的要求。例如,当emacs挂起(或计算机休眠)时,文件被更新(在DropBox中),计算机唤醒,文件被下载并带有更新时间戳,emacs进行检查,并查找最近5秒钟内的更改,错过了更新的文件。由于某种原因,它大多数时候都不能正常工作,而且从未在唤醒后工作。你能提出改进建议吗? - mankoff

2
Emacs与各种文件系统监视器库相连,并在filenotify.el中呈现统一的界面。

1

我没有一个完美的解决方案,但也许可以给你一些指针来帮助你找到正确的方向。

根据一些快速的谷歌搜索,似乎dbus已经内置了inotify接口。自从最新版本的emacs以来,你可以通过Emacs lisp(至少在Linux下)访问dbus接口,也许你可以将所有这些组合起来使其工作。这里有一个使用dbus与Emacs的例子:

http://emacs-fu.blogspot.com/2009/01/using-d-bus-example.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接