Function: file-notify-add-watch

file-notify-add-watch is a byte-compiled function defined in filenotify.el.gz.

Signature

(file-notify-add-watch FILE FLAGS CALLBACK)

Documentation

Add a watch for filesystem events pertaining to FILE.

This arranges for filesystem events pertaining to FILE to be reported to Emacs. Use file-notify-rm-watch to cancel the watch.

The returned value is a descriptor for the added watch. If the file cannot be watched for some reason, this function signals a file-notify-error error.

FLAGS is a list of conditions to set what will be watched for. It can include the following symbols:

  change -- watch for file changes
  attribute-change -- watch for file attributes changes, like
                        permissions or modification time

If FILE is a directory, change watches for file creation or deletion in that directory. Some of the file notification backends report also file changes. This does not work recursively.

When any event happens, Emacs will call the CALLBACK function passing it a single argument EVENT, which is of the form

  (DESCRIPTOR ACTION FILE [FILE1])

DESCRIPTOR is the same object as the one returned by this function. ACTION is the description of the event. It could be any one of the following:

  created -- FILE was created
  deleted -- FILE was deleted
  changed -- FILE has changed
  renamed -- FILE has been renamed to FILE1
  attribute-changed -- a FILE attribute was changed
  stopped -- watching FILE has been stopped

FILE is the name of the file whose event is being reported.

Probably introduced at or before Emacs version 24.4.

Source Code

;; Defined in /usr/src/emacs/lisp/filenotify.el.gz
(defun file-notify-add-watch (file flags callback)
  "Add a watch for filesystem events pertaining to FILE.
This arranges for filesystem events pertaining to FILE to be reported
to Emacs.  Use `file-notify-rm-watch' to cancel the watch.

The returned value is a descriptor for the added watch.  If the
file cannot be watched for some reason, this function signals a
`file-notify-error' error.

FLAGS is a list of conditions to set what will be watched for.  It can
include the following symbols:

  `change'           -- watch for file changes
  `attribute-change' -- watch for file attributes changes, like
                        permissions or modification time

If FILE is a directory, `change' watches for file creation or
deletion in that directory.  Some of the file notification
backends report also file changes.  This does not work
recursively.

When any event happens, Emacs will call the CALLBACK function passing
it a single argument EVENT, which is of the form

  (DESCRIPTOR ACTION FILE [FILE1])

DESCRIPTOR is the same object as the one returned by this function.
ACTION is the description of the event.  It could be any one of the
following:

  `created'           -- FILE was created
  `deleted'           -- FILE was deleted
  `changed'           -- FILE has changed
  `renamed'           -- FILE has been renamed to FILE1
  `attribute-changed' -- a FILE attribute was changed
  `stopped'           -- watching FILE has been stopped

FILE is the name of the file whose event is being reported."
  ;; Check arguments.
  (unless (stringp file)
    (signal 'wrong-type-argument `(,file)))
  (setq file (expand-file-name file))
  (unless (and (consp flags)
	       (null (delq 'change (delq 'attribute-change (copy-tree flags)))))
    (signal 'wrong-type-argument `(,flags)))
  (unless (functionp callback)
    (signal 'wrong-type-argument `(,callback)))

  (let ((handler (find-file-name-handler file 'file-notify-add-watch))
	(dir (directory-file-name
	      (if (file-directory-p file)
		  file
		(file-name-directory file)))))

    (unless (file-directory-p dir)
      (signal 'file-notify-error `("Directory does not exist" ,dir)))

    (let ((desc
           (if handler
               (funcall handler 'file-notify-add-watch dir flags callback)
             (funcall
              (pcase file-notify--library
                ('inotify     #'file-notify--add-watch-inotify)
                ('kqueue      #'file-notify--add-watch-kqueue)
                ('w32notify   #'file-notify--add-watch-w32notify)
                ('gfilenotify #'file-notify--add-watch-gfilenotify)
                (_ (signal 'file-notify-error
                           '("No file notification package available"))))
              file dir flags))))

      ;; Modify `file-notify-descriptors'.
      (let ((watch (file-notify--watch-make
                    ;; We do not want to enter quoted file names into the hash.
                    (file-name-unquote dir)
                    (unless (file-directory-p file)
                      (file-name-nondirectory file))
                    callback)))
        (puthash desc watch file-notify-descriptors))
      ;; Return descriptor.
      desc)))