Spec-Zone.ru › Elisp

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

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

Также возможно наблюдать за файловыми системами на удалённых машинах, см. Удаленные файлы в Справочнике GNU Emacs. Это не зависит от одной из библиотек, подключенных к Emacs.

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

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

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

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

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

Иногда смонтированные файловые системы не могут отслеживаться на предмет изменений файлов. Это не обнаруживается этой функцией, и поэтому возвращаемое значение, отличное от nil, не гарантирует, что изменения в файле 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-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-2022 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