Function: file-notify--handle-event

file-notify--handle-event is a byte-compiled function defined in filenotify.el.gz.

Signature

(file-notify--handle-event DESC ACTIONS FILE FILE1-OR-COOKIE)

Documentation

Handle an event returned from file notification.

DESC is the back-end descriptor. ACTIONS is a list of:
 created
 changed
 attribute-changed
 deleted
 renamed -- FILE is old name, FILE1-OR-COOKIE is new name or nil
 renamed-from -- FILE is old name, FILE1-OR-COOKIE is cookie or nil
 renamed-to -- FILE is new name, FILE1-OR-COOKIE is cookie or nil
 stopped -- no more events after this should be sent

Source Code

;; Defined in /usr/src/emacs/lisp/filenotify.el.gz
(defun file-notify--handle-event (desc actions file file1-or-cookie)
  "Handle an event returned from file notification.
DESC is the back-end descriptor.  ACTIONS is a list of:
 `created'
 `changed'
 `attribute-changed'
 `deleted'
 `renamed'           -- FILE is old name, FILE1-OR-COOKIE is new name or nil
 `renamed-from'      -- FILE is old name, FILE1-OR-COOKIE is cookie or nil
 `renamed-to'        -- FILE is new name, FILE1-OR-COOKIE is cookie or nil
 `stopped'           -- no more events after this should be sent"
  (when-let* ((watch (gethash desc file-notify-descriptors))
              (file (file-notify--expand-file-name watch file)))
    (while actions
      (let ((action (pop actions))
            (file1 nil))
        (when watch
          ;; We only handle {renamed,moved}-{from,to} pairs when these
          ;; arrive in order without anything else in-between.
          ;; If there is a pending rename that does not match this event,
          ;; then send the former as a deletion (since we don't know the
          ;; rename destination).
          (when file-notify--pending-rename
            (unless (and (equal (file-notify--rename-cookie
                                 file-notify--pending-rename)
                                file1-or-cookie)
                         (eq action 'renamed-to))
              (file-notify--call-handler
               (file-notify--rename-watch file-notify--pending-rename)
               (file-notify--rename-desc file-notify--pending-rename)
               'deleted
               (file-notify--rename-from-file file-notify--pending-rename)
               nil)
              (setq file-notify--pending-rename nil)))

          (cond
           ((eq action 'renamed)
            ;; A `renamed' event may not have a destination name;
            ;; if none, treat it as a deletion.
            (if file1-or-cookie
                (setq file1
                      (file-notify--expand-file-name watch file1-or-cookie))
              (setq action 'deleted)))
           ;; Make the event pending.
           ((eq action 'renamed-from)
            (setq file-notify--pending-rename
                  (file-notify--rename-make watch desc file file1-or-cookie)
                  action nil)
	    (run-at-time 0.1 nil #'file-notify--check-pending-rename))
           ;; Look for pending event.
           ((eq action 'renamed-to)
            (if file-notify--pending-rename
                (let ((pending-watch (file-notify--rename-watch
                                      file-notify--pending-rename))
                      (pending-desc (file-notify--rename-desc
                                     file-notify--pending-rename))
                      (from-file (file-notify--rename-from-file
                                  file-notify--pending-rename)))
                  (setq file1 file
                        file from-file)
                  ;; If the source is handled by another watch, we
                  ;; must fire the rename event there as well.
                  (unless (equal desc pending-desc)
                    (file-notify--call-handler
                     pending-watch pending-desc 'renamed file file1))
                  (setq file-notify--pending-rename nil
                        action 'renamed))
              (setq action 'created))))

          (when action
            (file-notify--call-handler watch desc action file file1)))

        ;; Stop handling.
        (when (or (eq action 'stopped)
                  (and watch (memq action '(deleted renamed))
                       ;; Not when a file is backed up.
                       (not (and (stringp file1) (backup-file-name-p file1)))
                       ;; Watched file or directory is concerned.
                       (string-equal
                        file (file-notify--watch-absolute-filename watch))))
          ;; Fire pending `renamed-from' event.
          (file-notify--check-pending-rename)
          (setq actions nil)
          ;; Make sure this is the last time the callback was invoked.
          (when (eq action 'stopped)
            (setf (file-notify--watch-callback watch) nil))
          (file-notify-rm-watch desc))))))