aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2016-04-19 11:05:55 +0200
committerMichael Albinus2016-04-19 11:05:55 +0200
commited54b3ff9760e7b73172aa296949dfcc7aba106e (patch)
tree07f13d97c30229d493233c7259707dd726b49791
parentc456627ffaf4e73e979883b56117cb91f164936b (diff)
downloademacs-ed54b3ff9760e7b73172aa296949dfcc7aba106e.tar.gz
emacs-ed54b3ff9760e7b73172aa296949dfcc7aba106e.zip
autorevert: Resume with polling if file is deleted
* lisp/autorevert.el: Use consistent wording in comments and docstrings. (auto-revert-mode): Add local function to `kill-buffer-hook'. (auto-revert-notify-handler): Improve handling of `stopped' event. * test/lisp/autorevert-tests.el (auto-revert-test02-auto-revert-deleted-file): New test. (auto-revert-test03-auto-revert-tail-mode) (auto-revert-test04-auto-revert-mode-dired): Rename them.
-rw-r--r--lisp/autorevert.el85
-rw-r--r--test/lisp/autorevert-tests.el73
2 files changed, 121 insertions, 37 deletions
diff --git a/lisp/autorevert.el b/lisp/autorevert.el
index bc9d58e1a00..1129af8a2fa 100644
--- a/lisp/autorevert.el
+++ b/lisp/autorevert.el
@@ -51,6 +51,12 @@
51;; Emacs. You should never even notice that this package is active 51;; Emacs. You should never even notice that this package is active
52;; (except that your buffers will be reverted, of course). 52;; (except that your buffers will be reverted, of course).
53;; 53;;
54;; If the file exists, Auto-Revert Mode updates the buffer based on
55;; its (possibly empty) contents. If the file no longer exists, then
56;; there is nothing to revert, so it does not modify the buffer. Once
57;; a deleted file corresponding to a buffer in Auto-Revert Mode
58;; reappears, Auto-Revert Mode continues to work.
59;;
54;; If Emacs is compiled with file notification support, notifications 60;; If Emacs is compiled with file notification support, notifications
55;; are used instead of checking the time stamp of the files. You can 61;; are used instead of checking the time stamp of the files. You can
56;; disable this by setting the user option `auto-revert-use-notify' to 62;; disable this by setting the user option `auto-revert-use-notify' to
@@ -58,19 +64,19 @@
58;; excluded from file notifications can be specified by 64;; excluded from file notifications can be specified by
59;; `auto-revert-notify-exclude-dir-regexp'. 65;; `auto-revert-notify-exclude-dir-regexp'.
60;; 66;;
61;; After reverting a file buffer, Auto Revert Mode normally puts point 67;; After reverting a file buffer, Auto-Revert Mode normally puts point
62;; at the same position that a regular manual revert would. However, 68;; at the same position that a regular manual revert would. However,
63;; there is one exception to this rule. If point is at the end of the 69;; there is one exception to this rule. If point is at the end of the
64;; buffer before reverting, it stays at the end. Similarly if point 70;; buffer before reverting, it stays at the end. Similarly if point
65;; is displayed at the end of a file buffer in any window, it will stay 71;; is displayed at the end of a file buffer in any window, it will stay
66;; at the end of the buffer in that window, even if the window is not 72;; at the end of the buffer in that window, even if the window is not
67;; selected. This way, you can use Auto Revert Mode to `tail' a file. 73;; selected. This way, you can use Auto-Revert Mode to `tail' a file.
68;; Just put point at the end of the buffer and it will stay there. 74;; Just put point at the end of the buffer and it will stay there.
69;; These rules apply to file buffers. For non-file buffers, the 75;; These rules apply to file buffers. For non-file buffers, the
70;; behavior may be mode dependent. 76;; behavior may be mode dependent.
71;; 77;;
72;; While you can use Auto Revert Mode to tail a file, this package 78;; While you can use Auto-Revert Mode to tail a file, this package
73;; contains a third minor mode, Auto Revert Tail Mode, which does so 79;; contains a third minor mode, Auto-Revert Tail Mode, which does so
74;; more efficiently, as long as you are sure that the file will only 80;; more efficiently, as long as you are sure that the file will only
75;; change by growing at the end. It only appends the new output, 81;; change by growing at the end. It only appends the new output,
76;; instead of reverting the entire buffer. It does so even if the 82;; instead of reverting the entire buffer. It does so even if the
@@ -112,8 +118,8 @@
112 118
113(defgroup auto-revert nil 119(defgroup auto-revert nil
114 "Revert individual buffers when files on disk change. 120 "Revert individual buffers when files on disk change.
115Auto-Revert mode enables auto-revert in individual buffers. 121Auto-Revert Mode enables auto-revert in individual buffers.
116Global Auto-Revert mode does so in all buffers." 122Global Auto-Revert Mode does so in all buffers."
117 :group 'files 123 :group 'files
118 :group 'convenience) 124 :group 'convenience)
119 125
@@ -144,7 +150,7 @@ If a timer is already active, there are two ways to make sure
144that the new value will take effect immediately. You can set 150that the new value will take effect immediately. You can set
145this variable through Custom or you can call the command 151this variable through Custom or you can call the command
146`auto-revert-set-timer' after setting the variable. Otherwise, 152`auto-revert-set-timer' after setting the variable. Otherwise,
147the new value will take effect the first time Auto Revert Mode 153the new value will take effect the first time Auto-Revert Mode
148calls `auto-revert-set-timer' for internal reasons or in your 154calls `auto-revert-set-timer' for internal reasons or in your
149next editing session." 155next editing session."
150 :group 'auto-revert 156 :group 'auto-revert
@@ -176,7 +182,7 @@ When non-nil, a message is generated whenever a file is reverted."
176 "String to display in the mode line when Auto-Revert Mode is active. 182 "String to display in the mode line when Auto-Revert Mode is active.
177 183
178\(When the string is not empty, make sure that it has a leading space.)" 184\(When the string is not empty, make sure that it has a leading space.)"
179 :tag "Auto Revert Mode Text" ; To separate it from `global-...' 185 :tag "Auto-Revert Mode Text" ; To separate it from `global-...'
180 :group 'auto-revert 186 :group 'auto-revert
181 :type 'string) 187 :type 'string)
182 188
@@ -190,7 +196,7 @@ When non-nil, a message is generated whenever a file is reverted."
190 196
191(defcustom auto-revert-mode-hook nil 197(defcustom auto-revert-mode-hook nil
192 "Functions to run when Auto-Revert Mode is activated." 198 "Functions to run when Auto-Revert Mode is activated."
193 :tag "Auto Revert Mode Hook" ; To separate it from `global-...' 199 :tag "Auto-Revert Mode Hook" ; To separate it from `global-...'
194 :group 'auto-revert 200 :group 'auto-revert
195 :type 'hook) 201 :type 'hook)
196 202
@@ -209,11 +215,11 @@ would only waste precious space."
209 :type 'hook) 215 :type 'hook)
210 216
211(defcustom global-auto-revert-non-file-buffers nil 217(defcustom global-auto-revert-non-file-buffers nil
212 "When nil, Global Auto-Revert mode operates only on file-visiting buffers. 218 "When nil, Global Auto-Revert Mode operates only on file-visiting buffers.
213 219
214When non-nil, both file buffers and buffers with a custom 220When non-nil, both file buffers and buffers with a custom
215`revert-buffer-function' and a `buffer-stale-function' are 221`revert-buffer-function' and a `buffer-stale-function' are
216reverted by Global Auto-Revert mode. These include the Buffer 222reverted by Global Auto-Revert Mode. These include the Buffer
217List buffer displayed by `buffer-menu', and Dired buffers showing 223List buffer displayed by `buffer-menu', and Dired buffers showing
218complete local directories. The Buffer List buffer reverts every 224complete local directories. The Buffer List buffer reverts every
219`auto-revert-interval' seconds; Dired buffers when the file list of 225`auto-revert-interval' seconds; Dired buffers when the file list of
@@ -240,8 +246,8 @@ For more information, see Info node `(emacs)Autorevert'."
240 :type 'hook) 246 :type 'hook)
241 247
242(defcustom auto-revert-check-vc-info nil 248(defcustom auto-revert-check-vc-info nil
243 "If non-nil Auto Revert Mode reliably updates version control info. 249 "If non-nil Auto-Revert Mode reliably updates version control info.
244Auto Revert Mode updates version control info whenever the buffer 250Auto-Revert Mode updates version control info whenever the buffer
245needs reverting, regardless of the value of this variable. 251needs reverting, regardless of the value of this variable.
246However, the version control state can change without changes to 252However, the version control state can change without changes to
247the work file. If the change is made from the current Emacs 253the work file. If the change is made from the current Emacs
@@ -271,7 +277,7 @@ This variable becomes buffer local when set in any fashion.")
271 :version "24.4") 277 :version "24.4")
272 278
273(defcustom auto-revert-use-notify t 279(defcustom auto-revert-use-notify t
274 "If non-nil Auto Revert Mode uses file notification functions. 280 "If non-nil Auto-Revert Mode uses file notification functions.
275You should set this variable through Custom." 281You should set this variable through Custom."
276 :group 'auto-revert 282 :group 'auto-revert
277 :type 'boolean 283 :type 'boolean
@@ -337,12 +343,12 @@ This has been reported by a file notification event.")
337 343
338;;;###autoload 344;;;###autoload
339(define-minor-mode auto-revert-mode 345(define-minor-mode auto-revert-mode
340 "Toggle reverting buffer when the file changes (Auto Revert mode). 346 "Toggle reverting buffer when the file changes (Auto-Revert Mode).
341With a prefix argument ARG, enable Auto Revert mode if ARG is 347With a prefix argument ARG, enable Auto-Revert Mode if ARG is
342positive, and disable it otherwise. If called from Lisp, enable 348positive, and disable it otherwise. If called from Lisp, enable
343the mode if ARG is omitted or nil. 349the mode if ARG is omitted or nil.
344 350
345Auto Revert mode is a minor mode that affects only the current 351Auto-Revert Mode is a minor mode that affects only the current
346buffer. When enabled, it reverts the buffer when the file on 352buffer. When enabled, it reverts the buffer when the file on
347disk changes. 353disk changes.
348 354
@@ -351,8 +357,14 @@ Use `auto-revert-tail-mode' if you know that the file will only grow
351without being changed in the part that is already in the buffer." 357without being changed in the part that is already in the buffer."
352 :group 'auto-revert :lighter auto-revert-mode-text 358 :group 'auto-revert :lighter auto-revert-mode-text
353 (if auto-revert-mode 359 (if auto-revert-mode
354 (if (not (memq (current-buffer) auto-revert-buffer-list)) 360 (when (not (memq (current-buffer) auto-revert-buffer-list))
355 (push (current-buffer) auto-revert-buffer-list)) 361 (push (current-buffer) auto-revert-buffer-list)
362 (add-hook
363 'kill-buffer-hook
364 (lambda ()
365 (setq auto-revert-buffer-list
366 (delq (current-buffer) auto-revert-buffer-list)))
367 nil t))
356 (when auto-revert-use-notify (auto-revert-notify-rm-watch)) 368 (when auto-revert-use-notify (auto-revert-notify-rm-watch))
357 (setq auto-revert-buffer-list 369 (setq auto-revert-buffer-list
358 (delq (current-buffer) auto-revert-buffer-list))) 370 (delq (current-buffer) auto-revert-buffer-list)))
@@ -374,11 +386,11 @@ This function is designed to be added to hooks, for example:
374;;;###autoload 386;;;###autoload
375(define-minor-mode auto-revert-tail-mode 387(define-minor-mode auto-revert-tail-mode
376 "Toggle reverting tail of buffer when the file grows. 388 "Toggle reverting tail of buffer when the file grows.
377With a prefix argument ARG, enable Auto-Revert Tail mode if ARG 389With a prefix argument ARG, enable Auto-Revert Tail Mode if ARG
378is positive, and disable it otherwise. If called from Lisp, 390is positive, and disable it otherwise. If called from Lisp,
379enable the mode if ARG is omitted or nil. 391enable the mode if ARG is omitted or nil.
380 392
381When Auto Revert Tail mode is enabled, the tail of the file is 393When Auto-Revert Tail Mode is enabled, the tail of the file is
382constantly followed, as with the shell command `tail -f'. This 394constantly followed, as with the shell command `tail -f'. This
383means that whenever the file grows on disk (presumably because 395means that whenever the file grows on disk (presumably because
384some background process is appending to it from time to time), 396some background process is appending to it from time to time),
@@ -428,7 +440,7 @@ Perform a full revert? ")
428 440
429;;;###autoload 441;;;###autoload
430(defun turn-on-auto-revert-tail-mode () 442(defun turn-on-auto-revert-tail-mode ()
431 "Turn on Auto-Revert Tail mode. 443 "Turn on Auto-Revert Tail Mode.
432 444
433This function is designed to be added to hooks, for example: 445This function is designed to be added to hooks, for example:
434 (add-hook \\='my-logfile-mode-hook #\\='turn-on-auto-revert-tail-mode)" 446 (add-hook \\='my-logfile-mode-hook #\\='turn-on-auto-revert-tail-mode)"
@@ -437,12 +449,12 @@ This function is designed to be added to hooks, for example:
437 449
438;;;###autoload 450;;;###autoload
439(define-minor-mode global-auto-revert-mode 451(define-minor-mode global-auto-revert-mode
440 "Toggle Global Auto Revert mode. 452 "Toggle Global Auto-Revert Mode.
441With a prefix argument ARG, enable Global Auto Revert mode if ARG 453With a prefix argument ARG, enable Global Auto-Revert Mode if ARG
442is positive, and disable it otherwise. If called from Lisp, 454is positive, and disable it otherwise. If called from Lisp,
443enable the mode if ARG is omitted or nil. 455enable the mode if ARG is omitted or nil.
444 456
445Global Auto Revert mode is a global minor mode that reverts any 457Global Auto-Revert Mode is a global minor mode that reverts any
446buffer associated with a file when the file changes on disk. Use 458buffer associated with a file when the file changes on disk. Use
447`auto-revert-mode' to revert a particular buffer. 459`auto-revert-mode' to revert a particular buffer.
448 460
@@ -573,16 +585,19 @@ no more reverts are possible until the next call of
573 585
574 (if (eq action 'stopped) 586 (if (eq action 'stopped)
575 ;; File notification has stopped. Continue with polling. 587 ;; File notification has stopped. Continue with polling.
576 (cl-dolist (buffer buffers) 588 (cl-dolist (buffer
589 (if global-auto-revert-mode
590 (buffer-list) auto-revert-buffer-list))
577 (with-current-buffer buffer 591 (with-current-buffer buffer
578 (when (or 592 (when (and (equal descriptor auto-revert-notify-watch-descriptor)
579 ;; A buffer associated with a file. 593 (or
580 (and (stringp buffer-file-name) 594 ;; A buffer associated with a file.
581 (string-equal 595 (and (stringp buffer-file-name)
582 (file-name-nondirectory file) 596 (string-equal
583 (file-name-nondirectory buffer-file-name))) 597 (file-name-nondirectory file)
584 ;; A buffer w/o a file, like dired. 598 (file-name-nondirectory buffer-file-name)))
585 (null buffer-file-name)) 599 ;; A buffer w/o a file, like dired.
600 (null buffer-file-name)))
586 (auto-revert-notify-rm-watch) 601 (auto-revert-notify-rm-watch)
587 (setq-local auto-revert-use-notify nil)))) 602 (setq-local auto-revert-use-notify nil))))
588 603
@@ -736,7 +751,7 @@ To avoid starvation, the buffers in `auto-revert-remaining-buffers'
736are checked first the next time this function is called. 751are checked first the next time this function is called.
737 752
738This function is also responsible for removing buffers no longer in 753This function is also responsible for removing buffers no longer in
739Auto-Revert mode from `auto-revert-buffer-list', and for canceling 754Auto-Revert Mode from `auto-revert-buffer-list', and for canceling
740the timer when no buffers need to be checked." 755the timer when no buffers need to be checked."
741 756
742 (setq auto-revert-buffers-counter 757 (setq auto-revert-buffers-counter
diff --git a/test/lisp/autorevert-tests.el b/test/lisp/autorevert-tests.el
index a6f8cb29563..2f951c0c9aa 100644
--- a/test/lisp/autorevert-tests.el
+++ b/test/lisp/autorevert-tests.el
@@ -156,7 +156,76 @@
156 (ignore-errors (delete-directory tmpdir1 'recursive)) 156 (ignore-errors (delete-directory tmpdir1 'recursive))
157 (ignore-errors (delete-directory tmpdir2 'recursive))))) 157 (ignore-errors (delete-directory tmpdir2 'recursive)))))
158 158
159(ert-deftest auto-revert-test02-auto-revert-tail-mode () 159;; This is inspired by Bug#23276.
160(ert-deftest auto-revert-test02-auto-revert-deleted-file ()
161 "Check autorevert for a deleted file."
162 :tags '(:expensive-test)
163
164 (let ((tmpfile (make-temp-file "auto-revert-test"))
165 buf)
166 (unwind-protect
167 (progn
168 (with-current-buffer (get-buffer-create "*Messages*")
169 (narrow-to-region (point-max) (point-max)))
170 (write-region "any text" nil tmpfile nil 'no-message)
171 (setq buf (find-file-noselect tmpfile))
172 (with-current-buffer buf
173 (should (string-equal (buffer-string) "any text"))
174 ;; `buffer-stale--default-function' checks for
175 ;; `verify-visited-file-modtime'. We must ensure that
176 ;; it returns nil.
177 (sleep-for 1)
178 (auto-revert-mode 1)
179 (should auto-revert-mode)
180
181 ;; Remove file while reverting. We simulate this by
182 ;; modifying `before-revert-hook'.
183 (add-hook
184 'before-revert-hook
185 (lambda () (delete-file buffer-file-name))
186 nil t)
187 (with-current-buffer (get-buffer-create "*Messages*")
188 (narrow-to-region (point-max) (point-max)))
189 (sleep-for 1)
190 (write-region "another text" nil tmpfile nil 'no-message)
191
192 ;; Check, that the buffer hasn't been reverted. File
193 ;; notification should be disabled, falling back to
194 ;; polling.
195 (auto-revert--wait-for-revert buf)
196 (should (string-match "any text" (buffer-string)))
197 (should-not auto-revert-use-notify)
198
199 ;; Once the file has been recreated, the buffer shall be
200 ;; reverted.
201 (kill-local-variable 'before-revert-hook)
202 (with-current-buffer (get-buffer-create "*Messages*")
203 (narrow-to-region (point-max) (point-max)))
204 (sleep-for 1)
205 (write-region "another text" nil tmpfile nil 'no-message)
206
207 ;; Check, that the buffer has been reverted.
208 (auto-revert--wait-for-revert buf)
209 (should (string-match "another text" (buffer-string)))
210
211 ;; An empty file shall still be reverted.
212 (with-current-buffer (get-buffer-create "*Messages*")
213 (narrow-to-region (point-max) (point-max)))
214 (sleep-for 1)
215 (write-region "" nil tmpfile nil 'no-message)
216
217 ;; Check, that the buffer has been reverted.
218 (auto-revert--wait-for-revert buf)
219 (should (string-equal "" (buffer-string)))))
220
221 ;; Exit.
222 (with-current-buffer "*Messages*" (widen))
223 (ignore-errors
224 (with-current-buffer buf (set-buffer-modified-p nil))
225 (kill-buffer buf))
226 (ignore-errors (delete-file tmpfile)))))
227
228(ert-deftest auto-revert-test03-auto-revert-tail-mode ()
160 "Check autorevert tail mode." 229 "Check autorevert tail mode."
161 ;; `auto-revert-buffers' runs every 5". And we must wait, until the 230 ;; `auto-revert-buffers' runs every 5". And we must wait, until the
162 ;; file has been reverted. 231 ;; file has been reverted.
@@ -194,7 +263,7 @@
194 (ignore-errors (kill-buffer buf)) 263 (ignore-errors (kill-buffer buf))
195 (ignore-errors (delete-file tmpfile))))) 264 (ignore-errors (delete-file tmpfile)))))
196 265
197(ert-deftest auto-revert-test03-auto-revert-mode-dired () 266(ert-deftest auto-revert-test04-auto-revert-mode-dired ()
198 "Check autorevert for dired." 267 "Check autorevert for dired."
199 ;; `auto-revert-buffers' runs every 5". And we must wait, until the 268 ;; `auto-revert-buffers' runs every 5". And we must wait, until the
200 ;; file has been reverted. 269 ;; file has been reverted.