Emacs Lisp, как отслеживать изменения файла / каталога

Я ищу способ периодически проверять, были ли файлы в определенном каталоге изменены с последней проверки (функциональность аналогична демону FAM или gio.monitor_directory). В emacs lisp.

  • Есть ли какая-либо библиотека / фрагмент, обеспечивающий эту функцию?
  • Если нет, как я могу реализовать такую ​​функцию?

person pygabriel    schedule 11.08.2010    source источник


Ответы (3)


(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.")
person huaiyuan    schedule 11.08.2010
comment
Этот фрагмент кода работает иногда, но не всегда, и технически не соответствует запросу «с момента последней проверки». Например, emacs приостановлен (или компьютер спит), файл обновлен (в DropBox), компьютер просыпается, файл загружается с отметкой времени обновления, emacs проверяет и ищет изменения не с момента последней проверки, а за последние 5 секунд, и пропускает файл обновления. По какой-то причине он не работает у меня большую часть времени, и никогда после пробуждения. Вы можете предложить улучшение? - person mankoff; 21.08.2012

У меня нет подходящего решения, но может быть пара указателей, которые укажут вам правильное направление.

Согласно некоторому быстрому поиску в Google кажется, что dbus имеет встроенный интерфейс inotify. Начиная с последней версии emacs, вы можете получить доступ к интерфейсу dbus через Emacs lisp (по крайней мере, под Linux), возможно, вы можете соединить все это вместе, чтобы оно работало. См. Здесь пример использования dbus с Emacs:

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

person Chmouel Boudjnah    schedule 11.08.2010

Emacs связан с различными библиотеками наблюдателей файловых систем и представляет единый интерфейс в filenotify.el.

person Radon Rosborough    schedule 22.06.2018