Spec-Zone.ru › Elisp

Уведомления об изменениях файлов

Некоторые операционные системы поддерживают отслеживание изменений файлов и их атрибутов в файловых системах. При правильной настройке Emacs статически подключает соответствующую библиотеку, например inotify, kqueue, gfilenotify или w32notify. Эти библиотеки позволяют отслеживать файловые системы на локальном компьютере.

Можно также отслеживать файловые системы на удалённых компьютерах; см. раздел Удалённые файлы в Руководстве по GNU Emacs. Для этого не требуется ни одна из библиотек, подключённых к Emacs.

Поскольку все эти библиотеки генерируют разные события при уведомлении об изменениях файлов, Emacs предоставляет специальную библиотеку filenotify, которая представляет приложениям унифицированный интерфейс. Программы на Lisp, которым нужны уведомления об изменениях файлов, всегда должны использовать эту библиотеку вместо нативных. В этом разделе описаны функции и переменные библиотеки filenotify.

Функция: file-notify-add-watch file flags callback

Добавляет отслеживание событий файловой системы, относящихся к file. Это позволяет передавать в Emacs уведомления о событиях файловой системы, относящихся к file.

Возвращаемое значение — дескриптор добавленного наблюдателя. Его тип зависит от используемой библиотеки, и в общем случае нельзя считать, что это целое число, как в примере ниже. Его следует использовать только для сравнения с помощью equal.

Если по какой-либо причине невозможно отслеживать file, функция сигнализирует об ошибке file-notify-error.

Иногда смонтированные файловые системы не позволяют отслеживать изменения файлов. Эта функция не обнаруживает такие ситуации, поэтому возвращаемое значение, отличное от nil, не гарантирует, что об изменениях file действительно будут поступать уведомления.

Если file — символическая ссылка, перехода по ней не происходит. Отслеживается только сам file.

flags — список условий, определяющих, что именно будет отслеживаться. Он может включать следующие символы:

change

отслеживать изменения содержимого файла

attribute-change

отслеживать изменения атрибутов файла, например прав доступа или времени изменения

Если file — каталог, change отслеживает создание и удаление файлов в этом каталоге. В этом случае некоторые нативные библиотеки уведомлений о файлах также сообщают об изменениях файлов. Рекурсивное отслеживание не поддерживается.

При возникновении любого события Emacs вызовет функцию callback, передав ей один аргумент event следующего вида:

(descriptor action file [file1])

descriptor — тот же объект, что и возвращённый этой функцией. action — описание события. Это может быть один из следующих символов:

created

file был создан

deleted

file был удалён

changed

содержимое file изменилось; библиотека w32notify также сообщает об изменениях атрибутов

renamed

file был переименован в file1

attribute-changed

атрибут file был изменён

stopped

отслеживание file прекращено

Обратите внимание, что библиотека w32notify не сообщает о событиях attribute-changed. При изменении атрибута файла, например прав доступа или времени изменения, эта библиотека сообщает о событии changed. Аналогично, библиотека kqueue при отслеживании каталога ненадёжно сообщает об изменениях атрибутов файлов.

Событие stopped означает, что отслеживание файла прекращено. Это может произойти из-за вызова file-notify-rm-watch (см. ниже), удаления отслеживаемого файла, размонтирования файловой системы, в которой находится отслеживаемый файл, или другой ошибки, сообщённой используемой библиотекой, из-за которой дальнейшее отслеживание невозможно.

file и file1 — имена файлов, о событиях с которыми сообщается. Например:

(require 'filenotify)
     ⇒ filenotify
(defun my-notify-callback (event)
  (message "Event %S" event))
     ⇒ my-notify-callback
(file-notify-add-watch
  "/tmp" '(change attribute-change) 'my-notify-callback)
     ⇒ 35025468
(write-region "foo" nil "/tmp/foo")
     ⇒ Event (35025468 created "/tmp/.#foo")
        Event (35025468 created "/tmp/foo")
        Event (35025468 changed "/tmp/foo")
        Event (35025468 deleted "/tmp/.#foo")
(write-region "bla" nil "/tmp/foo")
     ⇒ Event (35025468 created "/tmp/.#foo")
        Event (35025468 changed "/tmp/foo")
        Event (35025468 deleted "/tmp/.#foo")
(set-file-modes "/tmp/foo" (default-file-modes) 'nofollow)
     ⇒ Event (35025468 attribute-changed "/tmp/foo")

Возвращается ли действие renamed, зависит от используемой библиотеки отслеживания. В противном случае действия deleted и created могут возвращаться в случайном порядке.

(rename-file "/tmp/foo" "/tmp/bla")
     ⇒ Event (35025468 renamed "/tmp/foo" "/tmp/bla")
(delete-file "/tmp/bla")
     ⇒ Event (35025468 deleted "/tmp/bla")
Функция: file-notify-rm-watch descriptor

Удаляет существующий наблюдатель за файлом, заданный его descriptor. descriptor должен быть объектом, возвращённым функцией file-notify-add-watch.

Команда: file-notify-rm-all-watches

Удаляет все существующие наблюдатели за файлами в Emacs.

Используйте эту команду с осторожностью, поскольку она может непредвиденным образом повлиять на пакеты, использующие наблюдателей за файлами. Она предназначена главным образом для отладки или случаев, когда Emacs завис.

Функция: file-notify-valid-p descriptor

Проверяет действительность наблюдателя, заданного его descriptor. descriptor должен быть объектом, возвращённым функцией file-notify-add-watch.

Наблюдатель может стать недействительным, если отслеживаемый им файл или каталог удалён либо поток наблюдателя завершился аварийно по любой другой причине. Удаление наблюдателя вызовом file-notify-rm-watch также делает его недействительным.

(make-directory "/tmp/foo")
     ⇒ Event (35025468 created "/tmp/foo")
(setq desc
      (file-notify-add-watch
        "/tmp/foo" '(change) 'my-notify-callback))
     ⇒ 11359632
(file-notify-valid-p desc)
     ⇒ t
(write-region "bla" nil "/tmp/foo/bla")
     ⇒ Event (11359632 created "/tmp/foo/.#bla")
        Event (11359632 created "/tmp/foo/bla")
        Event (11359632 changed "/tmp/foo/bla")
        Event (11359632 deleted "/tmp/foo/.#bla")
;; Deleting a file in the directory doesn't invalidate the watch.
(delete-file "/tmp/foo/bla")
     ⇒ Event (11359632 deleted "/tmp/foo/bla")
(write-region "bla" nil "/tmp/foo/bla")
     ⇒ Event (11359632 created "/tmp/foo/.#bla")
        Event (11359632 created "/tmp/foo/bla")
        Event (11359632 changed "/tmp/foo/bla")
        Event (11359632 deleted "/tmp/foo/.#bla")
;; Deleting the directory invalidates the watch.
;; Events arrive for different watch descriptors.
(delete-directory "/tmp/foo" 'recursive)
     ⇒ Event (35025468 deleted "/tmp/foo")
        Event (11359632 deleted "/tmp/foo/bla")
        Event (11359632 deleted "/tmp/foo")
        Event (11359632 stopped "/tmp/foo")
(file-notify-valid-p desc)
     ⇒ nil

Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/File-Notifications.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API