@@ -262,9 +262,49 @@ EVENT is the cadr of the event in `file-notify-handle-event'
262
262
file (file-notify--event-watched-file event))))
263
263
(file-notify-rm-watch desc)))))))
264
264
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
+
268
308
(defun file-notify-add-watch (file flags callback )
269
309
" Add a watch for filesystem events pertaining to FILE.
270
310
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."
315
355
(dir (directory-file-name
316
356
(if (file-directory-p file)
317
357
file
318
- (file-name-directory file))))
319
- desc func l-flags)
358
+ (file-name-directory file)))))
320
359
321
360
(unless (file-directory-p dir)
322
361
(signal 'file-notify-error `(" Directory does not exist" , dir )))
323
362
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)))
382
386
383
387
(defun file-notify-rm-watch (descriptor )
384
388
" Remove an existing watch specified by its DESCRIPTOR.
0 commit comments