diff options
author | Michael Albinus <michael.albinus@gmx.de> | 2015-10-25 14:18:17 +0100 |
---|---|---|
committer | Michael Albinus <michael.albinus@gmx.de> | 2015-10-25 14:18:17 +0100 |
commit | ab116b19eda6bf42b11f7b902c749a77d7cb7683 (patch) | |
tree | b0b5cfb9181ff9000d4d4c93d714df02d92c27b4 /lisp/filenotify.el | |
parent | 92c63c6552fc71961f0bb941d651ac359b9e1edc (diff) | |
download | emacs-ab116b19eda6bf42b11f7b902c749a77d7cb7683.tar.gz |
Introduce `stopped' event in file notification
* lisp/filenotify.el (file-notify--rm-descriptor): New defun.
(file-notify-rm-watch): Use it.
(file-notify-callback): Implement `stopped' event.
(file-notify-add-watch): Mention `stopped' in the docstring.
Check, that upper directory exists.
* test/automated/file-notify-tests.el (file-notify-test01-add-watch):
Add two test cases.
(file-notify-test02-events): Handle also `stopped' event.
(file-notify-test04-file-validity): Add another test case.
Diffstat (limited to 'lisp/filenotify.el')
-rw-r--r-- | lisp/filenotify.el | 73 |
1 files changed, 57 insertions, 16 deletions
diff --git a/lisp/filenotify.el b/lisp/filenotify.el index b9f59dedfde..55d9028f252 100644 --- a/lisp/filenotify.el +++ b/lisp/filenotify.el @@ -48,6 +48,33 @@ The value in the hash table is a list Several values for a given DIR happen only for `inotify', when different files from the same directory are watched.") +(defun file-notify--rm-descriptor (descriptor) + "Remove DESCRIPTOR from `file-notify-descriptors'. +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)) + (dir (car registered))) + + (when (consp registered) + ;; Send `stopped' event. + (dolist (entry (cdr registered)) + (funcall (cdr entry) + `(,(file-notify--descriptor desc) stopped + ,(or (and (stringp (car entry)) + (expand-file-name (car entry) dir)) + dir)))) + + ;; Modify `file-notify-descriptors'. + (if (not file) + (remhash desc file-notify-descriptors) + (setcdr registered + (delete (assoc file (cdr registered)) (cdr registered))) + (if (null (cdr registered)) + (remhash desc file-notify-descriptors) + (puthash desc registered file-notify-descriptors)))))) + ;; This function is used by `gfilenotify', `inotify' and `w32notify' events. ;;;###autoload (defun file-notify-handle-event (event) @@ -111,7 +138,7 @@ EVENT is the cadr of the event in `file-notify-handle-event' (registered (gethash desc file-notify-descriptors)) (actions (nth 1 event)) (file (file-notify--event-file-name event)) - file1 callback pending-event) + file1 callback pending-event stopped) ;; Make actions a list. (unless (consp actions) (setq actions (cons actions nil))) @@ -158,6 +185,8 @@ EVENT is the cadr of the event in `file-notify-handle-event' 'renamed) ;; inotify, w32notify. + ((eq action 'ignored) + (setq stopped t actions nil)) ((eq action 'attrib) 'attribute-changed) ((memq action '(create added)) 'created) ((memq action '(modify modified)) 'changed) @@ -194,6 +223,17 @@ 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) + (string-equal + (or (file-name-nondirectory file) "") (car (cadr registered)))))) + ;; Apply callback. (when (and action (or @@ -213,7 +253,11 @@ EVENT is the cadr of the event in `file-notify-handle-event' `(,(file-notify--descriptor desc) ,action ,file ,file1)) (funcall callback - `(,(file-notify--descriptor desc) ,action ,file)))))))) + `(,(file-notify--descriptor desc) ,action ,file))))) + + ;; Modify `file-notify-descriptors'. + (when stopped + (file-notify--rm-descriptor (file-notify--descriptor desc)))))) ;; `gfilenotify' and `w32notify' return a unique descriptor for every ;; `file-notify-add-watch', while `inotify' returns a unique @@ -251,17 +295,18 @@ following: `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 (list 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 (list flags))) + (signal 'wrong-type-argument `(,flags))) (unless (functionp callback) - (signal 'wrong-type-argument (list callback))) + (signal 'wrong-type-argument `(,callback))) (let* ((handler (find-file-name-handler file 'file-notify-add-watch)) (dir (directory-file-name @@ -270,6 +315,9 @@ FILE is the name of the file whose event is being reported." (file-name-directory file)))) desc func l-flags registered) + (unless (file-directory-p dir) + (signal 'file-notify-error `("Directory does not exist" ,dir))) + (if handler ;; A file name handler could exist even if there is no local ;; file notification support. @@ -326,10 +374,10 @@ FILE is the name of the file whose event is being reported." DESCRIPTOR should be an object returned by `file-notify-add-watch'." (let* ((desc (if (consp descriptor) (car descriptor) descriptor)) (file (if (consp descriptor) (cdr descriptor))) - (dir (car (gethash desc file-notify-descriptors))) + (registered (gethash desc file-notify-descriptors)) + (dir (car registered)) (handler (and (stringp dir) - (find-file-name-handler dir 'file-notify-rm-watch))) - (registered (gethash desc file-notify-descriptors))) + (find-file-name-handler dir 'file-notify-rm-watch)))) (when (stringp dir) ;; Call low-level function. @@ -351,14 +399,7 @@ DESCRIPTOR should be an object returned by `file-notify-add-watch'." (file-notify-error nil))) ;; Modify `file-notify-descriptors'. - (if (not file) - (remhash desc file-notify-descriptors) - - (setcdr registered - (delete (assoc file (cdr registered)) (cdr registered))) - (if (null (cdr registered)) - (remhash desc file-notify-descriptors) - (puthash desc registered file-notify-descriptors)))))) + (file-notify--rm-descriptor descriptor)))) (defun file-notify-valid-p (descriptor) "Check a watch specified by its DESCRIPTOR. |