Omit buffer_slot_type_mismatch and use generic predicates to enforce
[bpt/emacs.git] / lisp / autorevert.el
CommitLineData
e8af40ee 1;;; autorevert.el --- revert buffers when files on disk change
4a35aff3 2
ab422c4d 3;; Copyright (C) 1997-1999, 2001-2013 Free Software Foundation, Inc.
4a35aff3 4
a468671a 5;; Author: Anders Lindgren <andersl@andersl.com>
f5f727f8 6;; Keywords: convenience
a468671a
GM
7;; Created: 1997-06-01
8;; Date: 1999-11-30
4a35aff3
RS
9
10;; This file is part of GNU Emacs.
11
eb3fa2cf 12;; GNU Emacs is free software: you can redistribute it and/or modify
4a35aff3 13;; it under the terms of the GNU General Public License as published by
eb3fa2cf
GM
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
4a35aff3
RS
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
eb3fa2cf 23;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
4a35aff3
RS
24
25;;; Commentary:
26
27;; Introduction:
28;;
29;; Whenever a file that Emacs is editing has been changed by another
48764ae2 30;; program the user normally has to execute the command `revert-buffer'
4a35aff3
RS
31;; to load the new content of the file into Emacs.
32;;
33;; This package contains two minor modes: Global Auto-Revert Mode and
48764ae2 34;; Auto-Revert Mode. Both modes automatically revert buffers
2d677766
LT
35;; whenever the corresponding files have been changed on disk and the
36;; buffer contains no unsaved changes.
4a35aff3 37;;
ae229809
LT
38;; Auto-Revert Mode can be activated for individual buffers. Global
39;; Auto-Revert Mode applies to all file buffers. (If the user option
40;; `global-auto-revert-non-file-buffers' is non-nil, it also applies
41;; to some non-file buffers. This option is disabled by default.)
42;; Since checking a remote file is too slow, these modes do not check
43;; or revert remote files.
4a35aff3 44;;
48764ae2
DL
45;; Both modes operate by checking the time stamp of all files at
46;; intervals of `auto-revert-interval'. The default is every five
47;; seconds. The check is aborted whenever the user actually uses
48;; Emacs. You should never even notice that this package is active
49;; (except that your buffers will be reverted, of course).
1f41bcba
LT
50;;
51;; After reverting a file buffer, Auto Revert Mode normally puts point
52;; at the same position that a regular manual revert would. However,
53;; there is one exception to this rule. If point is at the end of the
54;; buffer before reverting, it stays at the end. Similarly if point
55;; is displayed at the end of a file buffer in any window, it will stay
56;; at the end of the buffer in that window, even if the window is not
57;; selected. This way, you can use Auto Revert Mode to `tail' a file.
58;; Just put point at the end of the buffer and it will stay there.
59;; These rules apply to file buffers. For non-file buffers, the
60;; behavior may be mode dependent.
2d677766
LT
61;;
62;; While you can use Auto Revert Mode to tail a file, this package
63;; contains a third minor mode, Auto Revert Tail Mode, which does so
64;; more efficiently, as long as you are sure that the file will only
65;; change by growing at the end. It only appends the new output,
66;; instead of reverting the entire buffer. It does so even if the
67;; buffer contains unsaved changes. (Because they will not be lost.)
3eedbc85 68;; Auto Revert Tail Mode works also for remote files.
4a35aff3
RS
69
70;; Usage:
71;;
dddc748b 72;; Go to the appropriate buffer and press either of:
4a35aff3 73;; M-x auto-revert-mode RET
dddc748b 74;; M-x auto-revert-tail-mode RET
4a35aff3
RS
75;;
76;; To activate Global Auto-Revert Mode, press:
77;; M-x global-auto-revert-mode RET
78;;
48764ae2 79;; To activate Global Auto-Revert Mode every time Emacs is started
e1dbe924 80;; customize the option `global-auto-revert-mode' or the following
48764ae2 81;; line could be added to your ~/.emacs:
4a35aff3
RS
82;; (global-auto-revert-mode 1)
83;;
84;; The function `turn-on-auto-revert-mode' could be added to any major
85;; mode hook to activate Auto-Revert Mode for all buffers in that
86;; mode. For example, the following line will activate Auto-Revert
87;; Mode in all C mode buffers:
88;;
89;; (add-hook 'c-mode-hook 'turn-on-auto-revert-mode)
90
91;;; Code:
92
93;; Dependencies:
94
95(require 'timer)
0f98bc23 96
4a35aff3
RS
97;; Custom Group:
98;;
99;; The two modes will be placed next to Auto Save Mode under the
100;; Files group under Emacs.
101
102(defgroup auto-revert nil
48764ae2 103 "Revert individual buffers when files on disk change.
cf20dee0
CY
104Auto-Revert mode enables auto-revert in individual buffers.
105Global Auto-Revert mode does so in all buffers."
f5f727f8
DN
106 :group 'files
107 :group 'convenience)
4a35aff3
RS
108
109
110;; Variables:
111
dddc748b
DP
112;;; What's this?: ;; Autoload for the benefit of `make-mode-line-mouse-sensitive'.
113;;; What's this?: ;;;###autoload
4a35aff3 114(defvar auto-revert-mode nil
18cfb5a1 115 "Non-nil when Auto-Revert Mode is active.
0e4f9468
SM
116Never set this variable directly, use the command `auto-revert-mode' instead.")
117(put 'auto-revert-mode 'permanent-local t)
4a35aff3 118
dddc748b 119(defvar auto-revert-tail-mode nil
18cfb5a1 120 "Non-nil when Auto-Revert Tail Mode is active.
9e559f9b
LT
121Never set this variable directly, use the command
122`auto-revert-tail-mode' instead.")
dddc748b
DP
123(put 'auto-revert-tail-mode 'permanent-local t)
124
a2ac68f1
LT
125(defvar auto-revert-timer nil
126 "Timer used by Auto-Revert Mode.")
127
4a35aff3 128(defcustom auto-revert-interval 5
ad660075 129 "Time, in seconds, between Auto-Revert Mode file checks.
a2ac68f1
LT
130The value may be an integer or floating point number.
131
132If a timer is already active, there are two ways to make sure
133that the new value will take effect immediately. You can set
134this variable through Custom or you can call the command
135`auto-revert-set-timer' after setting the variable. Otherwise,
136the new value will take effect the first time Auto Revert Mode
137calls `auto-revert-set-timer' for internal reasons or in your
138next editing session."
4a35aff3 139 :group 'auto-revert
a2ac68f1
LT
140 :type 'number
141 :set (lambda (variable value)
142 (set-default variable value)
143 (and (boundp 'auto-revert-timer)
144 auto-revert-timer
145 (auto-revert-set-timer))))
4a35aff3
RS
146
147(defcustom auto-revert-stop-on-user-input t
6547d313 148 "When non-nil, user input temporarily interrupts Auto-Revert Mode.
6dbbc01d 149With this setting, Auto-Revert Mode checks for user input after
5433e578
LT
150handling each buffer and does not process any further buffers
151\(until the next run of the timer) if user input is available.
152When nil, Auto-Revert Mode checks files and reverts buffers,
153with quitting disabled, without paying attention to user input.
8a593054 154Thus, with this setting, Emacs might be non-responsive at times."
4a35aff3
RS
155 :group 'auto-revert
156 :type 'boolean)
157
158(defcustom auto-revert-verbose t
6547d313 159 "When nil, Auto-Revert Mode does not generate any messages.
0e5dcfd7 160When non-nil, a message is generated whenever a file is reverted."
4a35aff3
RS
161 :group 'auto-revert
162 :type 'boolean)
163
164(defcustom auto-revert-mode-text " ARev"
165 "String to display in the mode line when Auto-Revert Mode is active.
166
167\(When the string is not empty, make sure that it has a leading space.)"
168 :tag "Auto Revert Mode Text" ; To separate it from `global-...'
169 :group 'auto-revert
170 :type 'string)
171
dddc748b
DP
172(defcustom auto-revert-tail-mode-text " Tail"
173 "String to display in the mode line when Auto-Revert Tail Mode is active.
174
175\(When the string is not empty, make sure that it has a leading space.)"
176 :group 'auto-revert
0a306700 177 :type 'string
bf247b6e 178 :version "22.1")
dddc748b 179
4a35aff3
RS
180(defcustom auto-revert-mode-hook nil
181 "Functions to run when Auto-Revert Mode is activated."
182 :tag "Auto Revert Mode Hook" ; To separate it from `global-...'
183 :group 'auto-revert
184 :type 'hook)
185
186(defcustom global-auto-revert-mode-text ""
187 "String to display when Global Auto-Revert Mode is active.
188
189The default is nothing since when this mode is active this text doesn't
48764ae2 190vary over time, or between buffers. Hence mode line text
4a35aff3
RS
191would only waste precious space."
192 :group 'auto-revert
193 :type 'string)
194
195(defcustom global-auto-revert-mode-hook nil
196 "Hook called when Global Auto-Revert Mode is activated."
197 :group 'auto-revert
198 :type 'hook)
199
200(defcustom global-auto-revert-non-file-buffers nil
d9e4328d 201 "When nil, Global Auto-Revert mode operates only on file-visiting buffers.
4a35aff3
RS
202
203When non-nil, both file buffers and buffers with a custom
0e5dcfd7 204`revert-buffer-function' and a `buffer-stale-function' are
9ae0d84f 205reverted by Global Auto-Revert mode. These include the Buffer
fc2f6a26
GM
206List buffer displayed by `buffer-menu', and Dired buffers showing
207complete local directories. The Buffer List buffer reverts every
208`auto-revert-interval' seconds; Dired buffers when the file list of
209the main directory changes. Dired buffers do not auto-revert as
210a result of changes in subdirectories, or in the contents, size,
211modes, etc., of files. You may still sometimes want to revert
212them manually.
0e4f9468 213
d9e4328d 214Use this option with care since it could lead to excessive auto-reverts.
415053a1 215For more information, see Info node `(emacs)Autorevert'."
4a35aff3 216 :group 'auto-revert
843c51ae 217 :type 'boolean
415053a1 218 :link '(info-link "(emacs)Autorevert"))
4a35aff3 219
dddc748b 220(defcustom global-auto-revert-ignore-modes ()
4a35aff3
RS
221 "List of major modes Global Auto-Revert Mode should not check."
222 :group 'auto-revert
223 :type '(repeat sexp))
224
225(defcustom auto-revert-load-hook nil
226 "Functions to run when Auto-Revert Mode is first loaded."
227 :tag "Load Hook"
228 :group 'auto-revert
229 :type 'hook)
230
71c8db4c
LT
231(defcustom auto-revert-check-vc-info nil
232 "If non-nil Auto Revert Mode reliably updates version control info.
233Auto Revert Mode updates version control info whenever the buffer
234needs reverting, regardless of the value of this variable.
235However, the version control state can change without changes to
236the work file. If the change is made from the current Emacs
237session, all info is updated. But if, for instance, a new
238version is checked in from outside the current Emacs session, the
239version control number in the mode line, as well as other version
240control related information, may not be properly updated. If you
241are worried about this, set this variable to a non-nil value.
242
243This currently works by automatically updating the version
244control info every `auto-revert-interval' seconds. Nevertheless,
245it should not cause excessive CPU usage on a reasonably fast
246machine, if it does not apply to too many version controlled
f9478d4d 247buffers. CPU usage depends on the version control system."
71c8db4c
LT
248 :group 'auto-revert
249 :type 'boolean
bf247b6e 250 :version "22.1")
71c8db4c 251
4a35aff3 252(defvar global-auto-revert-ignore-buffer nil
18cfb5a1 253 "When non-nil, Global Auto-Revert Mode will not revert this buffer.
48764ae2 254This variable becomes buffer local when set in any fashion.")
4a35aff3
RS
255(make-variable-buffer-local 'global-auto-revert-ignore-buffer)
256
4a35aff3
RS
257;; Internal variables:
258
dddc748b 259(defvar auto-revert-buffer-list ()
4a35aff3
RS
260 "List of buffers in Auto-Revert Mode.
261
262Note that only Auto-Revert Mode, never Global Auto-Revert Mode, adds
263buffers to this list.
264
265The timer function `auto-revert-buffers' is responsible for purging
266the list of old buffers.")
267
dddc748b 268(defvar auto-revert-remaining-buffers ()
4a35aff3
RS
269 "Buffers not checked when user input stopped execution.")
270
dddc748b
DP
271(defvar auto-revert-tail-pos 0
272 "Position of last known end of file.")
273
274(add-hook 'find-file-hook
0917bb33
GM
275 (lambda ()
276 (set (make-local-variable 'auto-revert-tail-pos)
277 (nth 7 (file-attributes buffer-file-name)))))
4a35aff3
RS
278
279;; Functions:
280
281;;;###autoload
0e4f9468 282(define-minor-mode auto-revert-mode
06e21633
CY
283 "Toggle reverting buffer when the file changes (Auto Revert mode).
284With a prefix argument ARG, enable Auto Revert mode if ARG is
285positive, and disable it otherwise. If called from Lisp, enable
286the mode if ARG is omitted or nil.
287
288Auto Revert mode is a minor mode that affects only the current
289buffer. When enabled, it reverts the buffer when the file on
290disk changes.
4a35aff3 291
dddc748b
DP
292Use `global-auto-revert-mode' to automatically revert all buffers.
293Use `auto-revert-tail-mode' if you know that the file will only grow
294without being changed in the part that is already in the buffer."
834b5c1e 295 :group 'auto-revert :lighter auto-revert-mode-text
4a35aff3
RS
296 (if auto-revert-mode
297 (if (not (memq (current-buffer) auto-revert-buffer-list))
298 (push (current-buffer) auto-revert-buffer-list))
299 (setq auto-revert-buffer-list
300 (delq (current-buffer) auto-revert-buffer-list)))
301 (auto-revert-set-timer)
302 (when auto-revert-mode
dddc748b
DP
303 (auto-revert-buffers)
304 (setq auto-revert-tail-mode nil)))
4a35aff3
RS
305
306
307;;;###autoload
308(defun turn-on-auto-revert-mode ()
309 "Turn on Auto-Revert Mode.
310
311This function is designed to be added to hooks, for example:
312 (add-hook 'c-mode-hook 'turn-on-auto-revert-mode)"
313 (auto-revert-mode 1))
314
315
dddc748b
DP
316;;;###autoload
317(define-minor-mode auto-revert-tail-mode
06e21633
CY
318 "Toggle reverting tail of buffer when the file grows.
319With a prefix argument ARG, enable Auto-Revert Tail mode if ARG
320is positive, and disable it otherwise. If called from Lisp,
321enable the mode if ARG is omitted or nil.
dddc748b 322
06e21633
CY
323When Auto Revert Tail mode is enabled, the tail of the file is
324constantly followed, as with the shell command `tail -f'. This
325means that whenever the file grows on disk (presumably because
326some background process is appending to it from time to time),
327this is reflected in the current buffer.
dddc748b
DP
328
329You can edit the buffer and turn this mode off and on again as
330you please. But make sure the background process has stopped
331writing before you save the file!
332
333Use `auto-revert-mode' for changes other than appends!"
334 :group 'find-file :lighter auto-revert-tail-mode-text
335 (when auto-revert-tail-mode
336 (unless buffer-file-name
337 (auto-revert-tail-mode 0)
338 (error "This buffer is not visiting a file"))
339 (if (and (buffer-modified-p)
0917bb33 340 (zerop auto-revert-tail-pos) ; library was loaded only after finding file
dddc748b
DP
341 (not (y-or-n-p "Buffer is modified, so tail offset may be wrong. Proceed? ")))
342 (auto-revert-tail-mode 0)
0917bb33
GM
343 ;; a-r-tail-pos stores the size of the file at the time of the
344 ;; last revert. After this package loads, it adds a
345 ;; find-file-hook to set this variable every time a file is
346 ;; loaded. If the package is loaded only _after_ visiting the
347 ;; file to be reverted, then we have no idea what the value of
348 ;; a-r-tail-pos should have been when the file was visited. If
349 ;; the file has changed on disk in the meantime, all we can do
350 ;; is offer to revert the whole thing. If you choose not to
351 ;; revert, then you might miss some output then happened
352 ;; between visiting the file and activating a-r-t-mode.
353 (and (zerop auto-revert-tail-pos)
354 (not (verify-visited-file-modtime (current-buffer)))
355 (y-or-n-p "File changed on disk, content may be missing. \
356Perform a full revert? ")
357 ;; Use this (not just revert-buffer) for point-preservation.
358 (auto-revert-handler))
dddc748b
DP
359 ;; else we might reappend our own end when we save
360 (add-hook 'before-save-hook (lambda () (auto-revert-tail-mode 0)) nil t)
361 (or (local-variable-p 'auto-revert-tail-pos) ; don't lose prior position
f373470d 362 (set (make-local-variable 'auto-revert-tail-pos)
ced3c1e2 363 (nth 7 (file-attributes buffer-file-name))))
dddc748b
DP
364 ;; let auto-revert-mode set up the mechanism for us if it isn't already
365 (or auto-revert-mode
366 (let ((auto-revert-tail-mode t))
367 (auto-revert-mode 1)))
368 (setq auto-revert-mode nil))))
369
370
371;;;###autoload
372(defun turn-on-auto-revert-tail-mode ()
06e21633 373 "Turn on Auto-Revert Tail mode.
dddc748b
DP
374
375This function is designed to be added to hooks, for example:
376 (add-hook 'my-logfile-mode-hook 'turn-on-auto-revert-tail-mode)"
377 (auto-revert-tail-mode 1))
378
379
4a35aff3 380;;;###autoload
0e4f9468 381(define-minor-mode global-auto-revert-mode
fc2f6a26 382 "Toggle Global Auto Revert mode.
06e21633
CY
383With a prefix argument ARG, enable Global Auto Revert mode if ARG
384is positive, and disable it otherwise. If called from Lisp,
385enable the mode if ARG is omitted or nil.
fc2f6a26 386
06e21633
CY
387Global Auto Revert mode is a global minor mode that reverts any
388buffer associated with a file when the file changes on disk. Use
389`auto-revert-mode' to revert a particular buffer.
fc2f6a26
GM
390
391If `global-auto-revert-non-file-buffers' is non-nil, this mode
392may also revert some non-file buffers, as described in the
393documentation of that variable. It ignores buffers with modes
394matching `global-auto-revert-ignore-modes', and buffers with a
395non-nil vale of `global-auto-revert-ignore-buffer'.
396
397This function calls the hook `global-auto-revert-mode-hook'.
398It displays the text that `global-auto-revert-mode-text'
399specifies in the mode line."
0e4f9468 400 :global t :group 'auto-revert :lighter global-auto-revert-mode-text
4a35aff3
RS
401 (auto-revert-set-timer)
402 (when global-auto-revert-mode
0e4f9468 403 (auto-revert-buffers)))
4a35aff3
RS
404
405
406(defun auto-revert-set-timer ()
0e5dcfd7 407 "Restart or cancel the timer used by Auto-Revert Mode.
d97c8375 408If such a timer is active, cancel it. Start a new timer if
0e5dcfd7
LT
409Global Auto-Revert Mode is active or if Auto-Revert Mode is active
410in some buffer. Restarting the timer ensures that Auto-Revert Mode
411will use an up-to-date value of `auto-revert-interval'"
a2ac68f1 412 (interactive)
4a35aff3
RS
413 (if (timerp auto-revert-timer)
414 (cancel-timer auto-revert-timer))
0e4f9468
SM
415 (setq auto-revert-timer
416 (if (or global-auto-revert-mode auto-revert-buffer-list)
417 (run-with-timer auto-revert-interval
418 auto-revert-interval
dddc748b 419 'auto-revert-buffers))))
4a35aff3 420
ed35db71
EZ
421(defun auto-revert-active-p ()
422 "Check if auto-revert is active (in current buffer or globally)."
423 (or auto-revert-mode
dddc748b 424 auto-revert-tail-mode
ed35db71
EZ
425 (and
426 global-auto-revert-mode
427 (not global-auto-revert-ignore-buffer)
428 (not (memq major-mode
429 global-auto-revert-ignore-modes)))))
430
ed35db71 431(defun auto-revert-handler ()
0e5dcfd7
LT
432 "Revert current buffer, if appropriate.
433This is an internal function used by Auto-Revert Mode."
dddc748b 434 (when (or auto-revert-tail-mode (not (buffer-modified-p)))
fdc31e1d 435 (let* ((buffer (current-buffer)) size
dddc748b
DP
436 (revert
437 (or (and buffer-file-name
fdc31e1d 438 (if auto-revert-tail-mode
3eedbc85 439 ;; Tramp caches the file attributes. Setting
06641a47
JB
440 ;; `remote-file-name-inhibit-cache' forces Tramp
441 ;; to reread the values.
442 (let ((remote-file-name-inhibit-cache t))
8d815e3c
MA
443 (and (file-readable-p buffer-file-name)
444 (/= auto-revert-tail-pos
445 (setq size
446 (nth 7 (file-attributes
447 buffer-file-name))))))
3eedbc85 448 (and (not (file-remote-p buffer-file-name))
8f754691 449 (file-readable-p buffer-file-name)
3eedbc85 450 (not (verify-visited-file-modtime buffer)))))
2d677766 451 (and (or auto-revert-mode
dddc748b
DP
452 global-auto-revert-non-file-buffers)
453 revert-buffer-function
454 (boundp 'buffer-stale-function)
455 (functionp buffer-stale-function)
456 (funcall buffer-stale-function t))))
457 eob eoblist)
d4411cef 458 (when revert
71c8db4c
LT
459 (when (and auto-revert-verbose
460 (not (eq revert 'fast)))
633e0363 461 (message "Reverting buffer `%s'." (buffer-name)))
1f41bcba
LT
462 ;; If point (or a window point) is at the end of the buffer,
463 ;; we want to keep it at the end after reverting. This allows
464 ;; to tail a file.
465 (when buffer-file-name
466 (setq eob (eobp))
467 (walk-windows
06641a47
JB
468 (lambda (window)
469 (and (eq (window-buffer window) buffer)
470 (= (window-point window) (point-max))
471 (push window eoblist)))
1f41bcba 472 'no-mini t))
dddc748b 473 (if auto-revert-tail-mode
fdc31e1d 474 (auto-revert-tail-handler size)
7ebc19f9
RS
475 ;; Bind buffer-read-only in case user has done C-x C-q,
476 ;; so as not to forget that. This gives undesirable results
477 ;; when the file's mode changes, but that is less common.
90e118ab
LT
478 (let ((buffer-read-only buffer-read-only))
479 (revert-buffer 'ignore-auto 'dont-ask 'preserve-modes)))
1f41bcba
LT
480 (when buffer-file-name
481 (when eob (goto-char (point-max)))
482 (dolist (window eoblist)
483 (set-window-point window (point-max)))))
71c8db4c
LT
484 ;; `preserve-modes' avoids changing the (minor) modes. But we
485 ;; do want to reset the mode for VC, so we do it manually.
486 (when (or revert auto-revert-check-vc-info)
487 (vc-find-file-hook)))))
ed35db71 488
3eedbc85 489(defun auto-revert-tail-handler (size)
fdc31e1d 490 (let ((modified (buffer-modified-p))
ddd7c238 491 (inhibit-read-only t) ; Ignore.
dddc748b 492 (file buffer-file-name)
ddd7c238 493 (buffer-file-name nil)) ; Ignore that file has changed.
fdc31e1d 494 (when (/= auto-revert-tail-pos size)
ddd7c238 495 (run-hooks 'before-revert-hook)
d918508e 496 (undo-boundary)
dddc748b
DP
497 (save-restriction
498 (widen)
499 (save-excursion
500 (goto-char (point-max))
fdc31e1d
DK
501 (insert-file-contents file nil
502 (and (< auto-revert-tail-pos size)
503 auto-revert-tail-pos)
504 size)))
ddd7c238 505 (run-hooks 'after-revert-hook)
d918508e 506 (undo-boundary)
dddc748b 507 (setq auto-revert-tail-pos size)
ddd7c238 508 (restore-buffer-modified-p modified)))
dddc748b
DP
509 (set-visited-file-modtime))
510
4a35aff3
RS
511(defun auto-revert-buffers ()
512 "Revert buffers as specified by Auto-Revert and Global Auto-Revert Mode.
513
514Should `global-auto-revert-mode' be active all file buffers are checked.
515
516Should `auto-revert-mode' be active in some buffers, those buffers
517are checked.
518
0e5dcfd7
LT
519Non-file buffers that have a custom `revert-buffer-function' and
520a `buffer-stale-function' are reverted either when Auto-Revert
521Mode is active in that buffer, or when the variable
522`global-auto-revert-non-file-buffers' is non-nil and Global
523Auto-Revert Mode is active.
4a35aff3 524
48764ae2 525This function stops whenever there is user input. The buffers not
4a35aff3
RS
526checked are stored in the variable `auto-revert-remaining-buffers'.
527
528To avoid starvation, the buffers in `auto-revert-remaining-buffers'
529are checked first the next time this function is called.
530
48764ae2 531This function is also responsible for removing buffers no longer in
4a35aff3
RS
532Auto-Revert mode from `auto-revert-buffer-list', and for canceling
533the timer when no buffers need to be checked."
33512cbe
LT
534 (save-match-data
535 (let ((bufs (if global-auto-revert-mode
536 (buffer-list)
537 auto-revert-buffer-list))
538 (remaining ())
539 (new ()))
540 ;; Partition `bufs' into two halves depending on whether or not
541 ;; the buffers are in `auto-revert-remaining-buffers'. The two
542 ;; halves are then re-joined with the "remaining" buffers at the
543 ;; head of the list.
544 (dolist (buf auto-revert-remaining-buffers)
545 (if (memq buf bufs)
546 (push buf remaining)))
547 (dolist (buf bufs)
548 (if (not (memq buf remaining))
549 (push buf new)))
550 (setq bufs (nreverse (nconc new remaining)))
551 (while (and bufs
552 (not (and auto-revert-stop-on-user-input
553 (input-pending-p))))
554 (let ((buf (car bufs)))
aa657fbf 555 (if (buffer-live-p buf)
33512cbe
LT
556 (with-current-buffer buf
557 ;; Test if someone has turned off Auto-Revert Mode in a
558 ;; non-standard way, for example by changing major mode.
559 (if (and (not auto-revert-mode)
560 (not auto-revert-tail-mode)
561 (memq buf auto-revert-buffer-list))
562 (setq auto-revert-buffer-list
563 (delq buf auto-revert-buffer-list)))
564 (when (auto-revert-active-p) (auto-revert-handler)))
565 ;; Remove dead buffer from `auto-revert-buffer-list'.
566 (setq auto-revert-buffer-list
567 (delq buf auto-revert-buffer-list))))
568 (setq bufs (cdr bufs)))
569 (setq auto-revert-remaining-buffers bufs)
570 ;; Check if we should cancel the timer.
571 (when (and (not global-auto-revert-mode)
572 (null auto-revert-buffer-list))
573 (cancel-timer auto-revert-timer)
574 (setq auto-revert-timer nil)))))
4a35aff3
RS
575
576
577;; The end:
4a35aff3
RS
578(provide 'autorevert)
579
580(run-hooks 'auto-revert-load-hook)
581
e8af40ee 582;;; autorevert.el ends here