Auto-commit of generated files.
[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 50;;
ed911257 51;; If Emacs is compiled with file watch support, notifications are
a778dd57
MA
52;; used instead of checking the time stamp of the files. You can
53;; disable this by setting the user option `auto-revert-use-notify' to
54;; nil.
ed911257 55;;
1f41bcba
LT
56;; After reverting a file buffer, Auto Revert Mode normally puts point
57;; at the same position that a regular manual revert would. However,
58;; there is one exception to this rule. If point is at the end of the
59;; buffer before reverting, it stays at the end. Similarly if point
60;; is displayed at the end of a file buffer in any window, it will stay
61;; at the end of the buffer in that window, even if the window is not
62;; selected. This way, you can use Auto Revert Mode to `tail' a file.
63;; Just put point at the end of the buffer and it will stay there.
64;; These rules apply to file buffers. For non-file buffers, the
65;; behavior may be mode dependent.
2d677766
LT
66;;
67;; While you can use Auto Revert Mode to tail a file, this package
68;; contains a third minor mode, Auto Revert Tail Mode, which does so
69;; more efficiently, as long as you are sure that the file will only
70;; change by growing at the end. It only appends the new output,
71;; instead of reverting the entire buffer. It does so even if the
72;; buffer contains unsaved changes. (Because they will not be lost.)
3eedbc85 73;; Auto Revert Tail Mode works also for remote files.
4a35aff3
RS
74
75;; Usage:
76;;
dddc748b 77;; Go to the appropriate buffer and press either of:
4a35aff3 78;; M-x auto-revert-mode RET
dddc748b 79;; M-x auto-revert-tail-mode RET
4a35aff3
RS
80;;
81;; To activate Global Auto-Revert Mode, press:
82;; M-x global-auto-revert-mode RET
83;;
48764ae2 84;; To activate Global Auto-Revert Mode every time Emacs is started
e1dbe924 85;; customize the option `global-auto-revert-mode' or the following
48764ae2 86;; line could be added to your ~/.emacs:
4a35aff3
RS
87;; (global-auto-revert-mode 1)
88;;
89;; The function `turn-on-auto-revert-mode' could be added to any major
90;; mode hook to activate Auto-Revert Mode for all buffers in that
91;; mode. For example, the following line will activate Auto-Revert
92;; Mode in all C mode buffers:
93;;
94;; (add-hook 'c-mode-hook 'turn-on-auto-revert-mode)
95
96;;; Code:
97
98;; Dependencies:
99
96c421bb 100(eval-when-compile (require 'cl-lib))
4a35aff3 101(require 'timer)
0f98bc23 102
4a35aff3
RS
103;; Custom Group:
104;;
105;; The two modes will be placed next to Auto Save Mode under the
106;; Files group under Emacs.
107
108(defgroup auto-revert nil
48764ae2 109 "Revert individual buffers when files on disk change.
cf20dee0
CY
110Auto-Revert mode enables auto-revert in individual buffers.
111Global Auto-Revert mode does so in all buffers."
f5f727f8
DN
112 :group 'files
113 :group 'convenience)
4a35aff3
RS
114
115
116;; Variables:
117
dddc748b
DP
118;;; What's this?: ;; Autoload for the benefit of `make-mode-line-mouse-sensitive'.
119;;; What's this?: ;;;###autoload
4a35aff3 120(defvar auto-revert-mode nil
18cfb5a1 121 "Non-nil when Auto-Revert Mode is active.
0e4f9468
SM
122Never set this variable directly, use the command `auto-revert-mode' instead.")
123(put 'auto-revert-mode 'permanent-local t)
4a35aff3 124
dddc748b 125(defvar auto-revert-tail-mode nil
18cfb5a1 126 "Non-nil when Auto-Revert Tail Mode is active.
9e559f9b
LT
127Never set this variable directly, use the command
128`auto-revert-tail-mode' instead.")
dddc748b
DP
129(put 'auto-revert-tail-mode 'permanent-local t)
130
a2ac68f1
LT
131(defvar auto-revert-timer nil
132 "Timer used by Auto-Revert Mode.")
133
4a35aff3 134(defcustom auto-revert-interval 5
ad660075 135 "Time, in seconds, between Auto-Revert Mode file checks.
a2ac68f1
LT
136The value may be an integer or floating point number.
137
138If a timer is already active, there are two ways to make sure
139that the new value will take effect immediately. You can set
140this variable through Custom or you can call the command
141`auto-revert-set-timer' after setting the variable. Otherwise,
142the new value will take effect the first time Auto Revert Mode
143calls `auto-revert-set-timer' for internal reasons or in your
144next editing session."
4a35aff3 145 :group 'auto-revert
a2ac68f1
LT
146 :type 'number
147 :set (lambda (variable value)
148 (set-default variable value)
149 (and (boundp 'auto-revert-timer)
150 auto-revert-timer
151 (auto-revert-set-timer))))
4a35aff3
RS
152
153(defcustom auto-revert-stop-on-user-input t
6547d313 154 "When non-nil, user input temporarily interrupts Auto-Revert Mode.
6dbbc01d 155With this setting, Auto-Revert Mode checks for user input after
5433e578
LT
156handling each buffer and does not process any further buffers
157\(until the next run of the timer) if user input is available.
158When nil, Auto-Revert Mode checks files and reverts buffers,
159with quitting disabled, without paying attention to user input.
8a593054 160Thus, with this setting, Emacs might be non-responsive at times."
4a35aff3
RS
161 :group 'auto-revert
162 :type 'boolean)
163
164(defcustom auto-revert-verbose t
6547d313 165 "When nil, Auto-Revert Mode does not generate any messages.
0e5dcfd7 166When non-nil, a message is generated whenever a file is reverted."
4a35aff3
RS
167 :group 'auto-revert
168 :type 'boolean)
169
170(defcustom auto-revert-mode-text " ARev"
171 "String to display in the mode line when Auto-Revert Mode is active.
172
173\(When the string is not empty, make sure that it has a leading space.)"
174 :tag "Auto Revert Mode Text" ; To separate it from `global-...'
175 :group 'auto-revert
176 :type 'string)
177
dddc748b
DP
178(defcustom auto-revert-tail-mode-text " Tail"
179 "String to display in the mode line when Auto-Revert Tail Mode is active.
180
181\(When the string is not empty, make sure that it has a leading space.)"
182 :group 'auto-revert
0a306700 183 :type 'string
bf247b6e 184 :version "22.1")
dddc748b 185
4a35aff3
RS
186(defcustom auto-revert-mode-hook nil
187 "Functions to run when Auto-Revert Mode is activated."
188 :tag "Auto Revert Mode Hook" ; To separate it from `global-...'
189 :group 'auto-revert
190 :type 'hook)
191
192(defcustom global-auto-revert-mode-text ""
193 "String to display when Global Auto-Revert Mode is active.
194
195The default is nothing since when this mode is active this text doesn't
48764ae2 196vary over time, or between buffers. Hence mode line text
4a35aff3
RS
197would only waste precious space."
198 :group 'auto-revert
199 :type 'string)
200
201(defcustom global-auto-revert-mode-hook nil
202 "Hook called when Global Auto-Revert Mode is activated."
203 :group 'auto-revert
204 :type 'hook)
205
206(defcustom global-auto-revert-non-file-buffers nil
d9e4328d 207 "When nil, Global Auto-Revert mode operates only on file-visiting buffers.
4a35aff3
RS
208
209When non-nil, both file buffers and buffers with a custom
0e5dcfd7 210`revert-buffer-function' and a `buffer-stale-function' are
9ae0d84f 211reverted by Global Auto-Revert mode. These include the Buffer
fc2f6a26
GM
212List buffer displayed by `buffer-menu', and Dired buffers showing
213complete local directories. The Buffer List buffer reverts every
214`auto-revert-interval' seconds; Dired buffers when the file list of
215the main directory changes. Dired buffers do not auto-revert as
216a result of changes in subdirectories, or in the contents, size,
217modes, etc., of files. You may still sometimes want to revert
218them manually.
0e4f9468 219
d9e4328d 220Use this option with care since it could lead to excessive auto-reverts.
415053a1 221For more information, see Info node `(emacs)Autorevert'."
4a35aff3 222 :group 'auto-revert
843c51ae 223 :type 'boolean
415053a1 224 :link '(info-link "(emacs)Autorevert"))
4a35aff3 225
dddc748b 226(defcustom global-auto-revert-ignore-modes ()
4a35aff3
RS
227 "List of major modes Global Auto-Revert Mode should not check."
228 :group 'auto-revert
229 :type '(repeat sexp))
230
231(defcustom auto-revert-load-hook nil
232 "Functions to run when Auto-Revert Mode is first loaded."
233 :tag "Load Hook"
234 :group 'auto-revert
235 :type 'hook)
236
71c8db4c
LT
237(defcustom auto-revert-check-vc-info nil
238 "If non-nil Auto Revert Mode reliably updates version control info.
239Auto Revert Mode updates version control info whenever the buffer
240needs reverting, regardless of the value of this variable.
241However, the version control state can change without changes to
242the work file. If the change is made from the current Emacs
243session, all info is updated. But if, for instance, a new
244version is checked in from outside the current Emacs session, the
245version control number in the mode line, as well as other version
246control related information, may not be properly updated. If you
247are worried about this, set this variable to a non-nil value.
248
249This currently works by automatically updating the version
250control info every `auto-revert-interval' seconds. Nevertheless,
251it should not cause excessive CPU usage on a reasonably fast
252machine, if it does not apply to too many version controlled
f9478d4d 253buffers. CPU usage depends on the version control system."
71c8db4c
LT
254 :group 'auto-revert
255 :type 'boolean
bf247b6e 256 :version "22.1")
71c8db4c 257
4a35aff3 258(defvar global-auto-revert-ignore-buffer nil
18cfb5a1 259 "When non-nil, Global Auto-Revert Mode will not revert this buffer.
48764ae2 260This variable becomes buffer local when set in any fashion.")
4a35aff3
RS
261(make-variable-buffer-local 'global-auto-revert-ignore-buffer)
262
a778dd57
MA
263(defconst auto-revert-notify-enabled
264 (or (featurep 'inotify) (featurep 'w32notify))
265 "Non-nil when Emacs has been compiled with file watch support.")
266
267(defcustom auto-revert-use-notify auto-revert-notify-enabled
268 "If non-nil Auto Revert Mode uses file watch functions.
269This requires Emacs being compiled with file watch support (see
270`auto-revert-notify-enabled'). You should set this variable
271through Custom only."
272 :group 'auto-revert
273 :type 'boolean
274 :set (lambda (variable value)
275 (set-default variable (and auto-revert-notify-enabled value))
68a08a32 276 (unless (symbol-value variable)
a778dd57
MA
277 (when auto-revert-notify-enabled
278 (dolist (buf (buffer-list))
279 (with-current-buffer buf
68a08a32
MA
280 (when (symbol-value 'auto-revert-notify-watch-descriptor)
281 (auto-revert-notify-rm-watch)))))))
a778dd57
MA
282 :version "24.4")
283
4a35aff3
RS
284;; Internal variables:
285
dddc748b 286(defvar auto-revert-buffer-list ()
4a35aff3
RS
287 "List of buffers in Auto-Revert Mode.
288
289Note that only Auto-Revert Mode, never Global Auto-Revert Mode, adds
290buffers to this list.
291
292The timer function `auto-revert-buffers' is responsible for purging
293the list of old buffers.")
294
dddc748b 295(defvar auto-revert-remaining-buffers ()
4a35aff3
RS
296 "Buffers not checked when user input stopped execution.")
297
dddc748b
DP
298(defvar auto-revert-tail-pos 0
299 "Position of last known end of file.")
300
301(add-hook 'find-file-hook
0917bb33
GM
302 (lambda ()
303 (set (make-local-variable 'auto-revert-tail-pos)
304 (nth 7 (file-attributes buffer-file-name)))))
4a35aff3 305
ed911257
MA
306(defvar auto-revert-notify-watch-descriptor-hash-list
307 (make-hash-table :test 'equal)
308 "A hash table collecting all file watch descriptors.
309Hash key is a watch descriptor, hash value is the corresponding buffer.")
310
311(defvar auto-revert-notify-watch-descriptor nil
312 "The file watch descriptor active for the current buffer.")
2daddd9e 313(put 'auto-revert-notify-watch-descriptor 'permanent-local t)
ed911257
MA
314
315(defvar auto-revert-notify-modified-p nil
316 "Non-nil when file has been modified on the file system.
317This has been reported by a file watch event.")
318(make-variable-buffer-local 'auto-revert-notify-modified-p)
319
4a35aff3
RS
320;; Functions:
321
322;;;###autoload
0e4f9468 323(define-minor-mode auto-revert-mode
06e21633
CY
324 "Toggle reverting buffer when the file changes (Auto Revert mode).
325With a prefix argument ARG, enable Auto Revert mode if ARG is
326positive, and disable it otherwise. If called from Lisp, enable
327the mode if ARG is omitted or nil.
328
329Auto Revert mode is a minor mode that affects only the current
330buffer. When enabled, it reverts the buffer when the file on
331disk changes.
4a35aff3 332
dddc748b
DP
333Use `global-auto-revert-mode' to automatically revert all buffers.
334Use `auto-revert-tail-mode' if you know that the file will only grow
335without being changed in the part that is already in the buffer."
834b5c1e 336 :group 'auto-revert :lighter auto-revert-mode-text
4a35aff3
RS
337 (if auto-revert-mode
338 (if (not (memq (current-buffer) auto-revert-buffer-list))
339 (push (current-buffer) auto-revert-buffer-list))
a778dd57 340 (when auto-revert-use-notify (auto-revert-notify-rm-watch))
4a35aff3
RS
341 (setq auto-revert-buffer-list
342 (delq (current-buffer) auto-revert-buffer-list)))
343 (auto-revert-set-timer)
344 (when auto-revert-mode
dddc748b
DP
345 (auto-revert-buffers)
346 (setq auto-revert-tail-mode nil)))
4a35aff3
RS
347
348
349;;;###autoload
350(defun turn-on-auto-revert-mode ()
351 "Turn on Auto-Revert Mode.
352
353This function is designed to be added to hooks, for example:
354 (add-hook 'c-mode-hook 'turn-on-auto-revert-mode)"
355 (auto-revert-mode 1))
356
357
dddc748b
DP
358;;;###autoload
359(define-minor-mode auto-revert-tail-mode
06e21633
CY
360 "Toggle reverting tail of buffer when the file grows.
361With a prefix argument ARG, enable Auto-Revert Tail mode if ARG
362is positive, and disable it otherwise. If called from Lisp,
363enable the mode if ARG is omitted or nil.
dddc748b 364
06e21633
CY
365When Auto Revert Tail mode is enabled, the tail of the file is
366constantly followed, as with the shell command `tail -f'. This
367means that whenever the file grows on disk (presumably because
368some background process is appending to it from time to time),
369this is reflected in the current buffer.
dddc748b
DP
370
371You can edit the buffer and turn this mode off and on again as
372you please. But make sure the background process has stopped
373writing before you save the file!
374
375Use `auto-revert-mode' for changes other than appends!"
376 :group 'find-file :lighter auto-revert-tail-mode-text
377 (when auto-revert-tail-mode
378 (unless buffer-file-name
379 (auto-revert-tail-mode 0)
380 (error "This buffer is not visiting a file"))
381 (if (and (buffer-modified-p)
0917bb33 382 (zerop auto-revert-tail-pos) ; library was loaded only after finding file
dddc748b
DP
383 (not (y-or-n-p "Buffer is modified, so tail offset may be wrong. Proceed? ")))
384 (auto-revert-tail-mode 0)
0917bb33
GM
385 ;; a-r-tail-pos stores the size of the file at the time of the
386 ;; last revert. After this package loads, it adds a
387 ;; find-file-hook to set this variable every time a file is
388 ;; loaded. If the package is loaded only _after_ visiting the
389 ;; file to be reverted, then we have no idea what the value of
390 ;; a-r-tail-pos should have been when the file was visited. If
391 ;; the file has changed on disk in the meantime, all we can do
392 ;; is offer to revert the whole thing. If you choose not to
393 ;; revert, then you might miss some output then happened
394 ;; between visiting the file and activating a-r-t-mode.
395 (and (zerop auto-revert-tail-pos)
396 (not (verify-visited-file-modtime (current-buffer)))
397 (y-or-n-p "File changed on disk, content may be missing. \
398Perform a full revert? ")
399 ;; Use this (not just revert-buffer) for point-preservation.
400 (auto-revert-handler))
dddc748b
DP
401 ;; else we might reappend our own end when we save
402 (add-hook 'before-save-hook (lambda () (auto-revert-tail-mode 0)) nil t)
403 (or (local-variable-p 'auto-revert-tail-pos) ; don't lose prior position
f373470d 404 (set (make-local-variable 'auto-revert-tail-pos)
ced3c1e2 405 (nth 7 (file-attributes buffer-file-name))))
dddc748b
DP
406 ;; let auto-revert-mode set up the mechanism for us if it isn't already
407 (or auto-revert-mode
408 (let ((auto-revert-tail-mode t))
409 (auto-revert-mode 1)))
410 (setq auto-revert-mode nil))))
411
412
413;;;###autoload
414(defun turn-on-auto-revert-tail-mode ()
06e21633 415 "Turn on Auto-Revert Tail mode.
dddc748b
DP
416
417This function is designed to be added to hooks, for example:
418 (add-hook 'my-logfile-mode-hook 'turn-on-auto-revert-tail-mode)"
419 (auto-revert-tail-mode 1))
420
421
4a35aff3 422;;;###autoload
0e4f9468 423(define-minor-mode global-auto-revert-mode
fc2f6a26 424 "Toggle Global Auto Revert mode.
06e21633
CY
425With a prefix argument ARG, enable Global Auto Revert mode if ARG
426is positive, and disable it otherwise. If called from Lisp,
427enable the mode if ARG is omitted or nil.
fc2f6a26 428
06e21633
CY
429Global Auto Revert mode is a global minor mode that reverts any
430buffer associated with a file when the file changes on disk. Use
431`auto-revert-mode' to revert a particular buffer.
fc2f6a26
GM
432
433If `global-auto-revert-non-file-buffers' is non-nil, this mode
434may also revert some non-file buffers, as described in the
435documentation of that variable. It ignores buffers with modes
436matching `global-auto-revert-ignore-modes', and buffers with a
437non-nil vale of `global-auto-revert-ignore-buffer'.
438
439This function calls the hook `global-auto-revert-mode-hook'.
440It displays the text that `global-auto-revert-mode-text'
441specifies in the mode line."
0e4f9468 442 :global t :group 'auto-revert :lighter global-auto-revert-mode-text
4a35aff3 443 (auto-revert-set-timer)
ed911257
MA
444 (if global-auto-revert-mode
445 (auto-revert-buffers)
a778dd57 446 (when auto-revert-use-notify
ed911257
MA
447 (dolist (buf (buffer-list))
448 (with-current-buffer buf
449 (auto-revert-notify-rm-watch))))))
4a35aff3
RS
450
451(defun auto-revert-set-timer ()
0e5dcfd7 452 "Restart or cancel the timer used by Auto-Revert Mode.
d97c8375 453If such a timer is active, cancel it. Start a new timer if
0e5dcfd7
LT
454Global Auto-Revert Mode is active or if Auto-Revert Mode is active
455in some buffer. Restarting the timer ensures that Auto-Revert Mode
456will use an up-to-date value of `auto-revert-interval'"
a2ac68f1 457 (interactive)
4a35aff3
RS
458 (if (timerp auto-revert-timer)
459 (cancel-timer auto-revert-timer))
0e4f9468
SM
460 (setq auto-revert-timer
461 (if (or global-auto-revert-mode auto-revert-buffer-list)
462 (run-with-timer auto-revert-interval
463 auto-revert-interval
dddc748b 464 'auto-revert-buffers))))
4a35aff3 465
ed911257
MA
466(defun auto-revert-notify-rm-watch ()
467 "Disable file watch for current buffer's associated file."
468 (when auto-revert-notify-watch-descriptor
65adfa20
MA
469 (ignore-errors
470 (funcall (if (fboundp 'inotify-rm-watch)
471 'inotify-rm-watch 'w32notify-rm-watch)
472 auto-revert-notify-watch-descriptor))
ed911257 473 (remhash auto-revert-notify-watch-descriptor
68a08a32
MA
474 auto-revert-notify-watch-descriptor-hash-list)
475 (remove-hook 'kill-buffer-hook 'auto-revert-notify-rm-watch))
ed911257
MA
476 (setq auto-revert-notify-watch-descriptor nil
477 auto-revert-notify-modified-p nil))
478
479(defun auto-revert-notify-add-watch ()
480 "Enable file watch for current buffer's associated file."
68a08a32
MA
481 (when (and buffer-file-name auto-revert-use-notify
482 (not auto-revert-notify-watch-descriptor))
ed911257 483 (let ((func (if (fboundp 'inotify-add-watch)
10e714d5 484 'inotify-add-watch 'w32notify-add-watch))
ed911257 485 (aspect (if (fboundp 'inotify-add-watch)
65adfa20 486 '(modify) '(size last-write-time))))
ed911257 487 (setq auto-revert-notify-watch-descriptor
65adfa20
MA
488 (ignore-errors
489 (funcall
490 func buffer-file-name aspect 'auto-revert-notify-handler)))
491 (if auto-revert-notify-watch-descriptor
68a08a32
MA
492 (progn
493 (puthash auto-revert-notify-watch-descriptor
494 (current-buffer)
495 auto-revert-notify-watch-descriptor-hash-list)
496 (add-hook (make-local-variable 'kill-buffer-hook)
497 'auto-revert-notify-rm-watch))
65adfa20
MA
498 ;; Fallback to file checks.
499 (set (make-local-variable 'auto-revert-use-notify) nil)))))
500
501(defun auto-revert-notify-event-p (event)
502 "Check that event is a file watch event."
503 (cond ((featurep 'inotify)
504 (and (listp event) (= (length event) 4)))
505 ((featurep 'w32notify)
506 (and (listp event) (= (length event) 3) (stringp (nth 2 event))))))
507
508(defun auto-revert-notify-event-descriptor (event)
509 "Return watch descriptor of notification event, or nil."
510 (and (auto-revert-notify-event-p event) (car event)))
511
512(defun auto-revert-notify-event-action (event)
513 "Return action of notification event, or nil."
514 (and (auto-revert-notify-event-p event) (nth 1 event)))
515
516(defun auto-revert-notify-event-file-name (event)
517 "Return file name of notification event, or nil."
518 (and (auto-revert-notify-event-p event)
519 (cond ((featurep 'inotify) (nth 3 event))
520 ((featurep 'w32notify) (nth 2 event)))))
ed911257
MA
521
522(defun auto-revert-notify-handler (event)
523 "Handle an event returned from file watch."
65adfa20
MA
524 (when (auto-revert-notify-event-p event)
525 (let* ((descriptor (auto-revert-notify-event-descriptor event))
526 (action (auto-revert-notify-event-action event))
527 (file (auto-revert-notify-event-file-name event))
528 (buffer (gethash descriptor
529 auto-revert-notify-watch-descriptor-hash-list)))
65adfa20 530 (ignore-errors
c88be996
MA
531 ;; Check, that event is meant for us.
532 ;; TODO: Filter events which stop watching, like `move' or `removed'.
96c421bb 533 (cl-assert descriptor)
86fbb162
EZ
534 (when (featurep 'inotify) (cl-assert (memq 'modify action)))
535 (when (featurep 'w32notify) (cl-assert (eq 'modified action)))
96c421bb 536 (cl-assert (bufferp buffer))
c88be996 537 (with-current-buffer buffer
71c661e4
MA
538 (when (and (stringp file) (stringp buffer-file-name))
539 ;; w32notify returns the basename of the file without its
540 ;; leading directories; inotify returns its full absolute
541 ;; file name.
542 (cl-assert (file-equal-p file buffer-file-name)))
543
544 ;; Mark buffer modified.
c88be996 545 (setq auto-revert-notify-modified-p t))))))
ed911257 546
ed35db71
EZ
547(defun auto-revert-active-p ()
548 "Check if auto-revert is active (in current buffer or globally)."
549 (or auto-revert-mode
dddc748b 550 auto-revert-tail-mode
ed35db71
EZ
551 (and
552 global-auto-revert-mode
553 (not global-auto-revert-ignore-buffer)
554 (not (memq major-mode
555 global-auto-revert-ignore-modes)))))
556
ed35db71 557(defun auto-revert-handler ()
0e5dcfd7
LT
558 "Revert current buffer, if appropriate.
559This is an internal function used by Auto-Revert Mode."
dddc748b 560 (when (or auto-revert-tail-mode (not (buffer-modified-p)))
fdc31e1d 561 (let* ((buffer (current-buffer)) size
dddc748b
DP
562 (revert
563 (or (and buffer-file-name
65adfa20
MA
564 (or (not auto-revert-use-notify)
565 auto-revert-notify-modified-p)
fdc31e1d 566 (if auto-revert-tail-mode
3eedbc85 567 ;; Tramp caches the file attributes. Setting
06641a47
JB
568 ;; `remote-file-name-inhibit-cache' forces Tramp
569 ;; to reread the values.
570 (let ((remote-file-name-inhibit-cache t))
8d815e3c
MA
571 (and (file-readable-p buffer-file-name)
572 (/= auto-revert-tail-pos
573 (setq size
574 (nth 7 (file-attributes
575 buffer-file-name))))))
65adfa20
MA
576 (and (not (file-remote-p buffer-file-name))
577 (file-readable-p buffer-file-name)
578 (not (verify-visited-file-modtime buffer)))))
2d677766 579 (and (or auto-revert-mode
dddc748b
DP
580 global-auto-revert-non-file-buffers)
581 revert-buffer-function
582 (boundp 'buffer-stale-function)
583 (functionp buffer-stale-function)
584 (funcall buffer-stale-function t))))
585 eob eoblist)
d4411cef 586 (when revert
ed911257 587 (setq auto-revert-notify-modified-p nil)
71c8db4c
LT
588 (when (and auto-revert-verbose
589 (not (eq revert 'fast)))
633e0363 590 (message "Reverting buffer `%s'." (buffer-name)))
1f41bcba
LT
591 ;; If point (or a window point) is at the end of the buffer,
592 ;; we want to keep it at the end after reverting. This allows
593 ;; to tail a file.
594 (when buffer-file-name
595 (setq eob (eobp))
596 (walk-windows
06641a47
JB
597 (lambda (window)
598 (and (eq (window-buffer window) buffer)
599 (= (window-point window) (point-max))
600 (push window eoblist)))
1f41bcba 601 'no-mini t))
dddc748b 602 (if auto-revert-tail-mode
fdc31e1d 603 (auto-revert-tail-handler size)
7ebc19f9
RS
604 ;; Bind buffer-read-only in case user has done C-x C-q,
605 ;; so as not to forget that. This gives undesirable results
606 ;; when the file's mode changes, but that is less common.
90e118ab
LT
607 (let ((buffer-read-only buffer-read-only))
608 (revert-buffer 'ignore-auto 'dont-ask 'preserve-modes)))
1f41bcba
LT
609 (when buffer-file-name
610 (when eob (goto-char (point-max)))
611 (dolist (window eoblist)
612 (set-window-point window (point-max)))))
71c8db4c
LT
613 ;; `preserve-modes' avoids changing the (minor) modes. But we
614 ;; do want to reset the mode for VC, so we do it manually.
615 (when (or revert auto-revert-check-vc-info)
616 (vc-find-file-hook)))))
ed35db71 617
3eedbc85 618(defun auto-revert-tail-handler (size)
fdc31e1d 619 (let ((modified (buffer-modified-p))
ddd7c238 620 (inhibit-read-only t) ; Ignore.
dddc748b 621 (file buffer-file-name)
ddd7c238 622 (buffer-file-name nil)) ; Ignore that file has changed.
fdc31e1d 623 (when (/= auto-revert-tail-pos size)
ddd7c238 624 (run-hooks 'before-revert-hook)
d918508e 625 (undo-boundary)
dddc748b
DP
626 (save-restriction
627 (widen)
628 (save-excursion
629 (goto-char (point-max))
fdc31e1d
DK
630 (insert-file-contents file nil
631 (and (< auto-revert-tail-pos size)
632 auto-revert-tail-pos)
633 size)))
ddd7c238 634 (run-hooks 'after-revert-hook)
d918508e 635 (undo-boundary)
dddc748b 636 (setq auto-revert-tail-pos size)
ddd7c238 637 (restore-buffer-modified-p modified)))
dddc748b
DP
638 (set-visited-file-modtime))
639
4a35aff3
RS
640(defun auto-revert-buffers ()
641 "Revert buffers as specified by Auto-Revert and Global Auto-Revert Mode.
642
643Should `global-auto-revert-mode' be active all file buffers are checked.
644
645Should `auto-revert-mode' be active in some buffers, those buffers
646are checked.
647
0e5dcfd7
LT
648Non-file buffers that have a custom `revert-buffer-function' and
649a `buffer-stale-function' are reverted either when Auto-Revert
650Mode is active in that buffer, or when the variable
651`global-auto-revert-non-file-buffers' is non-nil and Global
652Auto-Revert Mode is active.
4a35aff3 653
48764ae2 654This function stops whenever there is user input. The buffers not
4a35aff3
RS
655checked are stored in the variable `auto-revert-remaining-buffers'.
656
657To avoid starvation, the buffers in `auto-revert-remaining-buffers'
658are checked first the next time this function is called.
659
48764ae2 660This function is also responsible for removing buffers no longer in
4a35aff3
RS
661Auto-Revert mode from `auto-revert-buffer-list', and for canceling
662the timer when no buffers need to be checked."
33512cbe
LT
663 (save-match-data
664 (let ((bufs (if global-auto-revert-mode
665 (buffer-list)
666 auto-revert-buffer-list))
667 (remaining ())
668 (new ()))
669 ;; Partition `bufs' into two halves depending on whether or not
670 ;; the buffers are in `auto-revert-remaining-buffers'. The two
671 ;; halves are then re-joined with the "remaining" buffers at the
672 ;; head of the list.
673 (dolist (buf auto-revert-remaining-buffers)
674 (if (memq buf bufs)
675 (push buf remaining)))
676 (dolist (buf bufs)
677 (if (not (memq buf remaining))
678 (push buf new)))
679 (setq bufs (nreverse (nconc new remaining)))
680 (while (and bufs
681 (not (and auto-revert-stop-on-user-input
682 (input-pending-p))))
683 (let ((buf (car bufs)))
aa657fbf 684 (if (buffer-live-p buf)
33512cbe
LT
685 (with-current-buffer buf
686 ;; Test if someone has turned off Auto-Revert Mode in a
687 ;; non-standard way, for example by changing major mode.
688 (if (and (not auto-revert-mode)
689 (not auto-revert-tail-mode)
690 (memq buf auto-revert-buffer-list))
691 (setq auto-revert-buffer-list
692 (delq buf auto-revert-buffer-list)))
ed911257
MA
693 (when (auto-revert-active-p)
694 ;; Enable file watches.
a778dd57 695 (when (and auto-revert-use-notify buffer-file-name
ed911257
MA
696 (not auto-revert-notify-watch-descriptor)
697 (auto-revert-notify-add-watch)))
698 (auto-revert-handler)))
33512cbe
LT
699 ;; Remove dead buffer from `auto-revert-buffer-list'.
700 (setq auto-revert-buffer-list
701 (delq buf auto-revert-buffer-list))))
702 (setq bufs (cdr bufs)))
703 (setq auto-revert-remaining-buffers bufs)
704 ;; Check if we should cancel the timer.
705 (when (and (not global-auto-revert-mode)
706 (null auto-revert-buffer-list))
707 (cancel-timer auto-revert-timer)
708 (setq auto-revert-timer nil)))))
4a35aff3
RS
709
710
711;; The end:
4a35aff3
RS
712(provide 'autorevert)
713
714(run-hooks 'auto-revert-load-hook)
715
e8af40ee 716;;; autorevert.el ends here