X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/fee9e3ff5e3181e5e477849b5db94e7e39a4e0c4..fdcf46d33eebc59e56a35fcea186c61aad3c81d0:/lisp/filenotify.el diff --git a/lisp/filenotify.el b/lisp/filenotify.el index faa801ee6e..61b6d240e6 100644 --- a/lisp/filenotify.el +++ b/lisp/filenotify.el @@ -27,6 +27,8 @@ ;;; Code: +(require 'cl-lib) + (defconst file-notify--library (cond ((featurep 'inotify) 'inotify) @@ -54,18 +56,15 @@ different files from the same directory are watched.") DESCRIPTOR should be an object returned by `file-notify-add-watch'. If it is registered in `file-notify-descriptors', a stopped event is sent." (let* ((desc (if (consp descriptor) (car descriptor) descriptor)) - (file (if (consp descriptor) (cdr descriptor))) (registered (gethash desc file-notify-descriptors)) + (file (if (consp descriptor) (cdr descriptor) (cl-caadr registered))) (dir (car registered))) (when (consp registered) ;; Send `stopped' event. - (dolist (entry (cdr registered)) - (funcall (cdr entry) - `(,descriptor stopped - ,(or (and (stringp (car entry)) - (expand-file-name (car entry) dir)) - dir)))) + (funcall + (cdr (assoc file (cdr registered))) + `(,descriptor stopped ,(if file (expand-file-name file dir) dir))) ;; Modify `file-notify-descriptors'. (if (not file) @@ -99,6 +98,15 @@ Otherwise, signal a `file-notify-error'." "A pending file notification events for a future `renamed' action. It is a form ((DESCRIPTOR ACTION FILE [FILE1-OR-COOKIE]) CALLBACK).") +(defun file-notify--event-watched-file (event) + "Return file or directory being watched. +Could be different from the directory watched by the backend library." + (let* ((desc (if (consp (car event)) (caar event) (car event))) + (registered (gethash desc file-notify-descriptors)) + (file (if (consp (car event)) (cdar event) (cl-caadr registered))) + (dir (car registered))) + (if file (expand-file-name file dir) dir))) + (defun file-notify--event-file-name (event) "Return file name of file notification event, or nil." (directory-file-name @@ -189,8 +197,10 @@ EVENT is the cadr of the event in `file-notify-handle-event' '(attribute-changed changed created deleted renamed)) action) ((memq action '(moved rename)) - (setq file1 (file-notify--event-file1-name event)) - 'renamed) + ;; The kqueue rename event does not return file1 in + ;; case a file monitor is established. + (if (setq file1 (file-notify--event-file1-name event)) + 'renamed 'deleted)) ((eq action 'ignored) (setq stopped t actions nil)) ((memq action '(attrib link)) 'attribute-changed) @@ -234,22 +244,6 @@ EVENT is the cadr of the event in `file-notify-handle-event' (funcall (cadr pending-event) (car pending-event)) (setq pending-event nil)) - ;; Check for stopped. - (setq - stopped - (or - stopped - (and - (memq action '(deleted renamed)) - (= (length (cdr registered)) 1) - (or - (string-equal - (file-name-nondirectory file) - (file-name-nondirectory (car registered))) - (string-equal - (file-name-nondirectory file) - (car (cadr registered))))))) - ;; Apply callback. (when (and action (or @@ -269,18 +263,26 @@ EVENT is the cadr of the event in `file-notify-handle-event' (nth 0 entry) (file-name-nondirectory file1))))) ;;(message ;;"file-notify-callback %S %S %S %S %S" - ;;(file-notify--descriptor desc file) action file file1 registered) + ;;(file-notify--descriptor desc (car entry)) + ;;action file file1 registered) (if file1 (funcall callback - `(,(file-notify--descriptor desc file) ,action ,file ,file1)) + `(,(file-notify--descriptor desc (car entry)) + ,action ,file ,file1)) (funcall callback - `(,(file-notify--descriptor desc file) ,action ,file))))) - - ;; Modify `file-notify-descriptors'. - (when stopped - (file-notify-rm-watch (file-notify--descriptor desc file)))))) + `(,(file-notify--descriptor desc (car entry)) ,action ,file)))) + + ;; Send `stopped' event. + (when (or stopped + (and (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--event-watched-file event)))) + (file-notify-rm-watch (file-notify--descriptor desc (car entry)))))))) ;; `kqueue', `gfilenotify' and `w32notify' return a unique descriptor ;; for every `file-notify-add-watch', while `inotify' returns a unique