From 530bb2dc68bbd8be8a90759992095cc2edc4efcf Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Sat, 20 Jan 2018 16:26:02 +0100 Subject: [PATCH] Use file notification in autorevert also for recreated files * lisp/autorevert.el (auto-revert-mode) (global-auto-revert-mode, auto-revert-notify-add-watch) (auto-revert-notify-handler, auto-revert-handler): Do not use buffer local `auto-revert-use-notify' anymore. * test/lisp/autorevert-tests.el (auto-revert-test02-auto-revert-deleted-file): Adapt test in order to check, that file notification is reenabled when possible. --- lisp/autorevert.el | 72 +++++++++++++++-------------------- test/lisp/autorevert-tests.el | 10 ++++- 2 files changed, 39 insertions(+), 43 deletions(-) diff --git a/lisp/autorevert.el b/lisp/autorevert.el index 7b8302695fa..da8942664b7 100644 --- a/lisp/autorevert.el +++ b/lisp/autorevert.el @@ -373,7 +373,7 @@ without being changed in the part that is already in the buffer." 'kill-buffer-hook #'auto-revert-remove-current-buffer nil t)) - (when auto-revert-use-notify (auto-revert-notify-rm-watch)) + (when auto-revert-notify-watch-descriptor (auto-revert-notify-rm-watch)) (auto-revert-remove-current-buffer)) (auto-revert-set-timer) (when auto-revert-mode @@ -486,7 +486,7 @@ specifies in the mode line." (auto-revert-buffers) (dolist (buf (buffer-list)) (with-current-buffer buf - (when auto-revert-use-notify + (when auto-revert-notify-watch-descriptor (auto-revert-notify-rm-watch)))))) (defun auto-revert-set-timer () @@ -524,38 +524,31 @@ will use an up-to-date value of `auto-revert-interval'" (defun auto-revert-notify-add-watch () "Enable file notification for current buffer's associated file." ;; We can assume that `buffer-file-name' and - ;; `auto-revert-use-notify' are non-nil. - (if (or (string-match auto-revert-notify-exclude-dir-regexp - (expand-file-name default-directory)) - (file-symlink-p (or buffer-file-name default-directory))) - - ;; Fallback to file checks. - (setq-local auto-revert-use-notify nil) - - (when (not auto-revert-notify-watch-descriptor) - (setq auto-revert-notify-watch-descriptor - (ignore-errors - (if buffer-file-name - (file-notify-add-watch - (expand-file-name buffer-file-name default-directory) - '(change attribute-change) - 'auto-revert-notify-handler) + ;; `auto-revert-notify-watch-descriptor' are non-nil. + (unless (or auto-revert-notify-watch-descriptor + (string-match auto-revert-notify-exclude-dir-regexp + (expand-file-name default-directory)) + (file-symlink-p (or buffer-file-name default-directory))) + (setq auto-revert-notify-watch-descriptor + (ignore-errors + (if buffer-file-name (file-notify-add-watch - (expand-file-name default-directory) - '(change) - 'auto-revert-notify-handler)))) - (if auto-revert-notify-watch-descriptor - (progn - (puthash - auto-revert-notify-watch-descriptor - (cons (current-buffer) - (gethash auto-revert-notify-watch-descriptor - auto-revert-notify-watch-descriptor-hash-list)) - auto-revert-notify-watch-descriptor-hash-list) - (add-hook 'kill-buffer-hook - #'auto-revert-notify-rm-watch nil t)) - ;; Fallback to file checks. - (setq-local auto-revert-use-notify nil))))) + (expand-file-name buffer-file-name default-directory) + '(change attribute-change) + 'auto-revert-notify-handler) + (file-notify-add-watch + (expand-file-name default-directory) + '(change) + 'auto-revert-notify-handler)))) + (when auto-revert-notify-watch-descriptor + (setq auto-revert-notify-modified-p t) + (puthash + auto-revert-notify-watch-descriptor + (cons (current-buffer) + (gethash auto-revert-notify-watch-descriptor + auto-revert-notify-watch-descriptor-hash-list)) + auto-revert-notify-watch-descriptor-hash-list) + (add-hook 'kill-buffer-hook #'auto-revert-notify-rm-watch nil t)))) ;; If we have file notifications, we want to update the auto-revert buffers ;; immediately when a notification occurs. Since file updates can happen very @@ -611,8 +604,7 @@ no more reverts are possible until the next call of (file-name-nondirectory buffer-file-name))) ;; A buffer w/o a file, like dired. (null buffer-file-name))) - (auto-revert-notify-rm-watch) - (setq-local auto-revert-use-notify nil)))) + (auto-revert-notify-rm-watch)))) ;; Loop over all buffers, in order to find the intended one. (cl-dolist (buffer buffers) @@ -651,11 +643,9 @@ no more reverts are possible until the next call of "Check if auto-revert is active (in current buffer or globally)." (or auto-revert-mode auto-revert-tail-mode - (and - global-auto-revert-mode - (not global-auto-revert-ignore-buffer) - (not (memq major-mode - global-auto-revert-ignore-modes))))) + (and global-auto-revert-mode + (not global-auto-revert-ignore-buffer) + (not (memq major-mode global-auto-revert-ignore-modes))))) (defun auto-revert-handler () "Revert current buffer, if appropriate. @@ -669,7 +659,7 @@ This is an internal function used by Auto-Revert Mode." (if buffer-file-name (and (or auto-revert-remote-files (not (file-remote-p buffer-file-name))) - (or (not auto-revert-use-notify) + (or (not auto-revert-notify-watch-descriptor) auto-revert-notify-modified-p) (if auto-revert-tail-mode (and (file-readable-p buffer-file-name) diff --git a/test/lisp/autorevert-tests.el b/test/lisp/autorevert-tests.el index 8f375b63a69..05d24b51ee7 100644 --- a/test/lisp/autorevert-tests.el +++ b/test/lisp/autorevert-tests.el @@ -161,7 +161,7 @@ This expects `auto-revert--messages' to be bound by :tags '(:expensive-test) (let ((tmpfile (make-temp-file "auto-revert-test")) - buf) + buf desc) (unwind-protect (progn (write-region "any text" nil tmpfile nil 'no-message) @@ -174,6 +174,7 @@ This expects `auto-revert--messages' to be bound by (sleep-for 1) (auto-revert-mode 1) (should auto-revert-mode) + (setq desc auto-revert-notify-watch-descriptor) ;; Remove file while reverting. We simulate this by ;; modifying `before-revert-hook'. @@ -192,7 +193,7 @@ This expects `auto-revert--messages' to be bound by (should (string-match "any text" (buffer-string))) ;; With w32notify, the 'stopped' events are not sent. (or (eq file-notify--library 'w32notify) - (should-not auto-revert-use-notify)) + (should-not auto-revert-notify-watch-descriptor)) ;; Once the file has been recreated, the buffer shall be ;; reverted. @@ -203,6 +204,11 @@ This expects `auto-revert--messages' to be bound by (auto-revert--wait-for-revert buf)) ;; Check, that the buffer has been reverted. (should (string-match "another text" (buffer-string))) + ;; When file notification is used, it must be reenabled + ;; after recreation of the file. We cannot expect that + ;; the descriptor is the same, so we just check the + ;; existence. + (should (eq (null desc) (null auto-revert-notify-watch-descriptor))) ;; An empty file shall still be reverted. (ert-with-message-capture auto-revert--messages -- 2.39.5