Skip to content

Commit e13b8c0

Browse files
committed
Small code clean-up of file-notify-add-watch
* lisp/filenotify.el (file-notify-add-watch): Clearly separate backend-specific code from the rest, and simplify. (file-notify--add-watch-inotify, file-notify--add-watch-kqueue) (file-notify--add-watch-w32notify, file-notify--add-watch-gfilenotify): New functions.
1 parent 0efaae7 commit e13b8c0

File tree

1 file changed

+67
-63
lines changed

1 file changed

+67
-63
lines changed

lisp/filenotify.el

Lines changed: 67 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,49 @@ EVENT is the cadr of the event in `file-notify-handle-event'
262262
file (file-notify--event-watched-file event))))
263263
(file-notify-rm-watch desc)))))))
264264

265-
;; `kqueue', `gfilenotify' and `w32notify' return a unique descriptor
266-
;; for every `file-notify-add-watch', while `inotify' returns a unique
267-
;; descriptor per inode only.
265+
(declare-function inotify-add-watch "inotify.c" (file flags callback))
266+
(declare-function kqueue-add-watch "kqueue.c" (file flags callback))
267+
(declare-function w32notify-add-watch "w32notify.c" (file flags callback))
268+
(declare-function gfile-add-watch "gfilenotify.c" (file flags callback))
269+
270+
(defun file-notify--add-watch-inotify (_file dir flags)
271+
"Add a watch for FILE in DIR with FLAGS, using inotify."
272+
(inotify-add-watch dir
273+
(append
274+
(and (memq 'change flags)
275+
'(create delete delete-self modify move-self move))
276+
(and (memq 'attribute-change flags)
277+
'(attrib)))
278+
#'file-notify-callback))
279+
280+
(defun file-notify--add-watch-kqueue (file _dir flags)
281+
"Add a watch for FILE in DIR with FLAGS, using kqueue."
282+
;; kqueue does not report changes to file contents when watching
283+
;; directories, so we watch each file directly.
284+
(kqueue-add-watch file
285+
(append
286+
(and (memq 'change flags)
287+
'(create delete write extend rename))
288+
(and (memq 'attribute-change flags)
289+
'(attrib)))
290+
#'file-notify-callback))
291+
292+
(defun file-notify--add-watch-w32notify (_file dir flags)
293+
"Add a watch for FILE in DIR with FLAGS, using w32notify."
294+
(w32notify-add-watch dir
295+
(append
296+
(and (memq 'change flags)
297+
'(file-name directory-name size last-write-time))
298+
(and (memq 'attribute-change flags)
299+
'(attributes)))
300+
#'file-notify-callback))
301+
302+
(defun file-notify--add-watch-gfilenotify (_file dir flags)
303+
"Add a watch for FILE in DIR with FLAGS, using gfilenotify."
304+
(gfile-add-watch dir
305+
(append '(watch-mounts send-moved) flags)
306+
#'file-notify-callback))
307+
268308
(defun file-notify-add-watch (file flags callback)
269309
"Add a watch for filesystem events pertaining to FILE.
270310
This arranges for filesystem events pertaining to FILE to be reported
@@ -315,70 +355,34 @@ FILE is the name of the file whose event is being reported."
315355
(dir (directory-file-name
316356
(if (file-directory-p file)
317357
file
318-
(file-name-directory file))))
319-
desc func l-flags)
358+
(file-name-directory file)))))
320359

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

324-
(if handler
325-
;; A file name handler could exist even if there is no local
326-
;; file notification support.
327-
(setq desc (funcall handler 'file-notify-add-watch dir flags callback))
328-
329-
;; Check, whether Emacs has been compiled with file notification
330-
;; support.
331-
(unless file-notify--library
332-
(signal 'file-notify-error
333-
'("No file notification package available")))
334-
335-
;; Determine low-level function to be called.
336-
(setq func
337-
(cond
338-
((eq file-notify--library 'inotify) 'inotify-add-watch)
339-
((eq file-notify--library 'kqueue) 'kqueue-add-watch)
340-
((eq file-notify--library 'gfilenotify) 'gfile-add-watch)
341-
((eq file-notify--library 'w32notify) 'w32notify-add-watch)))
342-
343-
;; Determine respective flags.
344-
(if (eq file-notify--library 'gfilenotify)
345-
(setq l-flags (append '(watch-mounts send-moved) flags))
346-
(when (memq 'change flags)
347-
(setq
348-
l-flags
349-
(cond
350-
((eq file-notify--library 'inotify)
351-
'(create delete delete-self modify move-self move))
352-
((eq file-notify--library 'kqueue)
353-
'(create delete write extend rename))
354-
((eq file-notify--library 'w32notify)
355-
'(file-name directory-name size last-write-time)))))
356-
(when (memq 'attribute-change flags)
357-
(push (cond
358-
((eq file-notify--library 'inotify) 'attrib)
359-
((eq file-notify--library 'kqueue) 'attrib)
360-
((eq file-notify--library 'w32notify) 'attributes))
361-
l-flags)))
362-
363-
;; Call low-level function.
364-
(setq desc (funcall
365-
;; kqueue does not report file changes in directory
366-
;; monitor. So we must watch the file itself.
367-
func (if (eq file-notify--library 'kqueue) file dir)
368-
l-flags 'file-notify-callback)))
369-
370-
;; We do not want to enter quoted file names into the hash.
371-
(setq file (file-name-unquote file)
372-
dir (file-name-unquote dir))
373-
374-
;; Modify `file-notify-descriptors'.
375-
(let ((watch (file-notify--watch-make
376-
dir
377-
(unless (file-directory-p file) (file-name-nondirectory file))
378-
callback)))
379-
(puthash desc watch file-notify-descriptors))
380-
;; Return descriptor.
381-
desc))
363+
(let ((desc
364+
(if handler
365+
(funcall handler 'file-notify-add-watch dir flags callback)
366+
(funcall
367+
(pcase file-notify--library
368+
('inotify #'file-notify--add-watch-inotify)
369+
('kqueue #'file-notify--add-watch-kqueue)
370+
('w32notify #'file-notify--add-watch-w32notify)
371+
('gfilenotify #'file-notify--add-watch-gfilenotify)
372+
(_ (signal 'file-notify-error
373+
'("No file notification package available"))))
374+
file dir flags))))
375+
376+
;; Modify `file-notify-descriptors'.
377+
(let ((watch (file-notify--watch-make
378+
;; We do not want to enter quoted file names into the hash.
379+
(file-name-unquote dir)
380+
(unless (file-directory-p file)
381+
(file-name-nondirectory file))
382+
callback)))
383+
(puthash desc watch file-notify-descriptors))
384+
;; Return descriptor.
385+
desc)))
382386

383387
(defun file-notify-rm-watch (descriptor)
384388
"Remove an existing watch specified by its DESCRIPTOR.

0 commit comments

Comments
 (0)