]> code.delx.au - gnu-emacs/blob - lisp/autorevert.el
Dired recognize dirs when file size in human units
[gnu-emacs] / lisp / autorevert.el
1 ;;; autorevert.el --- revert buffers when files on disk change -*- lexical-binding:t -*-
2
3 ;; Copyright (C) 1997-1999, 2001-2016 Free Software Foundation, Inc.
4
5 ;; Author: Anders Lindgren
6 ;; Keywords: convenience
7 ;; Created: 1997-06-01
8 ;; Date: 1999-11-30
9
10 ;; This file is part of GNU Emacs.
11
12 ;; GNU Emacs is free software: you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation, either version 3 of the License, or
15 ;; (at your option) any later version.
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
23 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
24
25 ;;; Commentary:
26
27 ;; Introduction:
28 ;;
29 ;; Whenever a file that Emacs is editing has been changed by another
30 ;; program the user normally has to execute the command `revert-buffer'
31 ;; to load the new content of the file into Emacs.
32 ;;
33 ;; This package contains two minor modes: Global Auto-Revert Mode and
34 ;; Auto-Revert Mode. Both modes automatically revert buffers
35 ;; whenever the corresponding files have been changed on disk and the
36 ;; buffer contains no unsaved changes.
37 ;;
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 ;;
43 ;; Since checking a remote file is slow, these modes check or revert
44 ;; remote files only if the user option `auto-revert-remote-files' is
45 ;; non-nil. It is recommended to disable version control for remote
46 ;; files.
47 ;;
48 ;; Both modes operate by checking the time stamp of all files at
49 ;; intervals of `auto-revert-interval'. The default is every five
50 ;; seconds. The check is aborted whenever the user actually uses
51 ;; Emacs. You should never even notice that this package is active
52 ;; (except that your buffers will be reverted, of course).
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 ;;
60 ;; If Emacs is compiled with file notification support, notifications
61 ;; are used instead of checking the time stamp of the files. You can
62 ;; disable this by setting the user option `auto-revert-use-notify' to
63 ;; nil. Alternatively, a regular expression of directories to be
64 ;; excluded from file notifications can be specified by
65 ;; `auto-revert-notify-exclude-dir-regexp'.
66 ;;
67 ;; After reverting a file buffer, Auto-Revert Mode normally puts point
68 ;; at the same position that a regular manual revert would. However,
69 ;; there is one exception to this rule. If point is at the end of the
70 ;; buffer before reverting, it stays at the end. Similarly if point
71 ;; is displayed at the end of a file buffer in any window, it will stay
72 ;; at the end of the buffer in that window, even if the window is not
73 ;; selected. This way, you can use Auto-Revert Mode to `tail' a file.
74 ;; Just put point at the end of the buffer and it will stay there.
75 ;; These rules apply to file buffers. For non-file buffers, the
76 ;; behavior may be mode dependent.
77 ;;
78 ;; While you can use Auto-Revert Mode to tail a file, this package
79 ;; contains a third minor mode, Auto-Revert Tail Mode, which does so
80 ;; more efficiently, as long as you are sure that the file will only
81 ;; change by growing at the end. It only appends the new output,
82 ;; instead of reverting the entire buffer. It does so even if the
83 ;; buffer contains unsaved changes. (Because they will not be lost.)
84
85 ;; Usage:
86 ;;
87 ;; Go to the appropriate buffer and press either of:
88 ;; M-x auto-revert-mode RET
89 ;; M-x auto-revert-tail-mode RET
90 ;;
91 ;; To activate Global Auto-Revert Mode, press:
92 ;; M-x global-auto-revert-mode RET
93 ;;
94 ;; To activate Global Auto-Revert Mode every time Emacs is started
95 ;; customize the option `global-auto-revert-mode' or the following
96 ;; line could be added to your ~/.emacs:
97 ;; (global-auto-revert-mode 1)
98 ;;
99 ;; The function `turn-on-auto-revert-mode' could be added to any major
100 ;; mode hook to activate Auto-Revert Mode for all buffers in that
101 ;; mode. For example, the following line will activate Auto-Revert
102 ;; Mode in all C mode buffers:
103 ;;
104 ;; (add-hook 'c-mode-hook #'turn-on-auto-revert-mode)
105
106 ;;; Code:
107
108 ;; Dependencies:
109
110 (eval-when-compile (require 'cl-lib))
111 (require 'timer)
112 (require 'filenotify)
113
114 ;; Custom Group:
115 ;;
116 ;; The two modes will be placed next to Auto Save Mode under the
117 ;; Files group under Emacs.
118
119 (defgroup auto-revert nil
120 "Revert individual buffers when files on disk change.
121 Auto-Revert Mode enables auto-revert in individual buffers.
122 Global Auto-Revert Mode does so in all buffers."
123 :group 'files
124 :group 'convenience)
125
126
127 ;; Variables:
128
129 ;;; What's this?: ;; Autoload for the benefit of `make-mode-line-mouse-sensitive'.
130 ;;; What's this?: ;;;###autoload
131 (defvar auto-revert-mode nil
132 "Non-nil when Auto-Revert Mode is active.
133 Never set this variable directly, use the command `auto-revert-mode' instead.")
134 (put 'auto-revert-mode 'permanent-local t)
135
136 (defvar auto-revert-tail-mode nil
137 "Non-nil when Auto-Revert Tail Mode is active.
138 Never set this variable directly, use the command
139 `auto-revert-tail-mode' instead.")
140 (put 'auto-revert-tail-mode 'permanent-local t)
141
142 (defvar auto-revert-timer nil
143 "Timer used by Auto-Revert Mode.")
144
145 (defcustom auto-revert-interval 5
146 "Time, in seconds, between Auto-Revert Mode file checks.
147 The value may be an integer or floating point number.
148
149 If a timer is already active, there are two ways to make sure
150 that the new value will take effect immediately. You can set
151 this variable through Custom or you can call the command
152 `auto-revert-set-timer' after setting the variable. Otherwise,
153 the new value will take effect the first time Auto-Revert Mode
154 calls `auto-revert-set-timer' for internal reasons or in your
155 next editing session."
156 :group 'auto-revert
157 :type 'number
158 :set (lambda (variable value)
159 (set-default variable value)
160 (and (boundp 'auto-revert-timer)
161 auto-revert-timer
162 (auto-revert-set-timer))))
163
164 (defcustom auto-revert-stop-on-user-input t
165 "When non-nil, user input temporarily interrupts Auto-Revert Mode.
166 With this setting, Auto-Revert Mode checks for user input after
167 handling each buffer and does not process any further buffers
168 \(until the next run of the timer) if user input is available.
169 When nil, Auto-Revert Mode checks files and reverts buffers,
170 with quitting disabled, without paying attention to user input.
171 Thus, with this setting, Emacs might be non-responsive at times."
172 :group 'auto-revert
173 :type 'boolean)
174
175 (defcustom auto-revert-verbose t
176 "When nil, Auto-Revert Mode does not generate any messages.
177 When non-nil, a message is generated whenever a file is reverted."
178 :group 'auto-revert
179 :type 'boolean)
180
181 (defcustom auto-revert-mode-text " ARev"
182 "String to display in the mode line when Auto-Revert Mode is active.
183
184 \(When the string is not empty, make sure that it has a leading space.)"
185 :tag "Auto-Revert Mode Text" ; To separate it from `global-...'
186 :group 'auto-revert
187 :type 'string)
188
189 (defcustom auto-revert-tail-mode-text " Tail"
190 "String to display in the mode line when Auto-Revert Tail Mode is active.
191
192 \(When the string is not empty, make sure that it has a leading space.)"
193 :group 'auto-revert
194 :type 'string
195 :version "22.1")
196
197 (defcustom auto-revert-mode-hook nil
198 "Functions to run when Auto-Revert Mode is activated."
199 :tag "Auto-Revert Mode Hook" ; To separate it from `global-...'
200 :group 'auto-revert
201 :type 'hook)
202
203 (defcustom global-auto-revert-mode-text ""
204 "String to display when Global Auto-Revert Mode is active.
205
206 The default is nothing since when this mode is active this text doesn't
207 vary over time, or between buffers. Hence mode line text
208 would only waste precious space."
209 :group 'auto-revert
210 :type 'string)
211
212 (defcustom global-auto-revert-mode-hook nil
213 "Hook called when Global Auto-Revert Mode is activated."
214 :group 'auto-revert
215 :type 'hook)
216
217 (defcustom global-auto-revert-non-file-buffers nil
218 "When nil, Global Auto-Revert Mode operates only on file-visiting buffers.
219
220 When non-nil, both file buffers and buffers with a custom
221 `revert-buffer-function' and a `buffer-stale-function' are
222 reverted by Global Auto-Revert Mode. These include the Buffer
223 List buffer displayed by `buffer-menu', and Dired buffers showing
224 complete local directories. The Buffer List buffer reverts every
225 `auto-revert-interval' seconds; Dired buffers when the file list of
226 the main directory changes. Dired buffers do not auto-revert as
227 a result of changes in subdirectories, or in the contents, size,
228 modes, etc., of files. You may still sometimes want to revert
229 them manually.
230
231 Use this option with care since it could lead to excessive auto-reverts.
232 For more information, see Info node `(emacs)Autorevert'."
233 :group 'auto-revert
234 :type 'boolean
235 :link '(info-link "(emacs)Autorevert"))
236
237 (defcustom global-auto-revert-ignore-modes ()
238 "List of major modes Global Auto-Revert Mode should not check."
239 :group 'auto-revert
240 :type '(repeat sexp))
241
242 (defcustom auto-revert-load-hook nil
243 "Functions to run when Auto-Revert Mode is first loaded."
244 :tag "Load Hook"
245 :group 'auto-revert
246 :type 'hook)
247
248 (defcustom auto-revert-check-vc-info nil
249 "If non-nil Auto-Revert Mode reliably updates version control info.
250 Auto-Revert Mode updates version control info whenever the buffer
251 needs reverting, regardless of the value of this variable.
252 However, the version control state can change without changes to
253 the work file. If the change is made from the current Emacs
254 session, all info is updated. But if, for instance, a new
255 version is checked in from outside the current Emacs session, the
256 version control number in the mode line, as well as other version
257 control related information, may not be properly updated. If you
258 are worried about this, set this variable to a non-nil value.
259
260 This currently works by automatically updating the version
261 control info every `auto-revert-interval' seconds. Nevertheless,
262 it should not cause excessive CPU usage on a reasonably fast
263 machine, if it does not apply to too many version controlled
264 buffers. CPU usage depends on the version control system."
265 :group 'auto-revert
266 :type 'boolean
267 :version "22.1")
268
269 (defvar-local global-auto-revert-ignore-buffer nil
270 "When non-nil, Global Auto-Revert Mode will not revert this buffer.
271 This variable becomes buffer local when set in any fashion.")
272
273 (defcustom auto-revert-remote-files nil
274 "If non-nil remote files are also reverted."
275 :group 'auto-revert
276 :type 'boolean
277 :version "24.4")
278
279 (defcustom auto-revert-use-notify t
280 "If non-nil Auto-Revert Mode uses file notification functions.
281 You should set this variable through Custom."
282 :group 'auto-revert
283 :type 'boolean
284 :set (lambda (variable value)
285 (set-default variable value)
286 (unless (symbol-value variable)
287 (dolist (buf (buffer-list))
288 (with-current-buffer buf
289 (when (symbol-value 'auto-revert-notify-watch-descriptor)
290 (auto-revert-notify-rm-watch))))))
291 :initialize 'custom-initialize-default
292 :version "24.4")
293
294 (defcustom auto-revert-notify-exclude-dir-regexp
295 (concat
296 ;; No mounted file systems.
297 "^" (regexp-opt '("/afs/" "/media/" "/mnt" "/net/" "/tmp_mnt/"))
298 ;; No remote files.
299 (unless auto-revert-remote-files "\\|^/[^/|:][^/|]+:"))
300 "Regular expression of directories to be excluded from file notifications."
301 :group 'auto-revert
302 :type 'regexp
303 :version "24.4")
304
305 ;; Internal variables:
306
307 (defvar auto-revert-buffer-list ()
308 "List of buffers in Auto-Revert Mode.
309
310 Note that only Auto-Revert Mode, never Global Auto-Revert Mode, adds
311 buffers to this list.
312
313 The timer function `auto-revert-buffers' is responsible for purging
314 the list of old buffers.")
315
316 (defvar auto-revert-remaining-buffers ()
317 "Buffers not checked when user input stopped execution.")
318
319 (defvar auto-revert-tail-pos 0
320 "Position of last known end of file.")
321
322 (add-hook 'find-file-hook
323 (lambda ()
324 (setq-local auto-revert-tail-pos
325 (nth 7 (file-attributes buffer-file-name)))))
326
327 (defvar auto-revert-notify-watch-descriptor-hash-list
328 (make-hash-table :test 'equal)
329 "A hash table collecting all file watch descriptors.
330 Hash key is a watch descriptor, hash value is a list of buffers
331 which are related to files being watched and carrying the same
332 default directory.")
333
334 (defvar-local auto-revert-notify-watch-descriptor nil
335 "The file watch descriptor active for the current buffer.")
336 (put 'auto-revert-notify-watch-descriptor 'permanent-local t)
337
338 (defvar-local auto-revert-notify-modified-p nil
339 "Non-nil when file has been modified on the file system.
340 This has been reported by a file notification event.")
341
342 ;; Functions:
343
344 ;;;###autoload
345 (define-minor-mode auto-revert-mode
346 "Toggle reverting buffer when the file changes (Auto-Revert Mode).
347 With a prefix argument ARG, enable Auto-Revert Mode if ARG is
348 positive, and disable it otherwise. If called from Lisp, enable
349 the mode if ARG is omitted or nil.
350
351 Auto-Revert Mode is a minor mode that affects only the current
352 buffer. When enabled, it reverts the buffer when the file on
353 disk changes.
354
355 Use `global-auto-revert-mode' to automatically revert all buffers.
356 Use `auto-revert-tail-mode' if you know that the file will only grow
357 without being changed in the part that is already in the buffer."
358 :group 'auto-revert :lighter auto-revert-mode-text
359 (if auto-revert-mode
360 (when (not (memq (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))
368 (when auto-revert-use-notify (auto-revert-notify-rm-watch))
369 (setq auto-revert-buffer-list
370 (delq (current-buffer) auto-revert-buffer-list)))
371 (auto-revert-set-timer)
372 (when auto-revert-mode
373 (auto-revert-buffers)
374 (setq auto-revert-tail-mode nil)))
375
376
377 ;;;###autoload
378 (defun turn-on-auto-revert-mode ()
379 "Turn on Auto-Revert Mode.
380
381 This function is designed to be added to hooks, for example:
382 (add-hook \\='c-mode-hook #\\='turn-on-auto-revert-mode)"
383 (auto-revert-mode 1))
384
385
386 ;;;###autoload
387 (define-minor-mode auto-revert-tail-mode
388 "Toggle reverting tail of buffer when the file grows.
389 With a prefix argument ARG, enable Auto-Revert Tail Mode if ARG
390 is positive, and disable it otherwise. If called from Lisp,
391 enable the mode if ARG is omitted or nil.
392
393 When Auto-Revert Tail Mode is enabled, the tail of the file is
394 constantly followed, as with the shell command `tail -f'. This
395 means that whenever the file grows on disk (presumably because
396 some background process is appending to it from time to time),
397 this is reflected in the current buffer.
398
399 You can edit the buffer and turn this mode off and on again as
400 you please. But make sure the background process has stopped
401 writing before you save the file!
402
403 Use `auto-revert-mode' for changes other than appends!"
404 :group 'find-file :lighter auto-revert-tail-mode-text
405 (when auto-revert-tail-mode
406 (unless buffer-file-name
407 (auto-revert-tail-mode 0)
408 (error "This buffer is not visiting a file"))
409 (if (and (buffer-modified-p)
410 (zerop auto-revert-tail-pos) ; library was loaded only after finding file
411 (not (y-or-n-p "Buffer is modified, so tail offset may be wrong. Proceed? ")))
412 (auto-revert-tail-mode 0)
413 ;; a-r-tail-pos stores the size of the file at the time of the
414 ;; last revert. After this package loads, it adds a
415 ;; find-file-hook to set this variable every time a file is
416 ;; loaded. If the package is loaded only _after_ visiting the
417 ;; file to be reverted, then we have no idea what the value of
418 ;; a-r-tail-pos should have been when the file was visited. If
419 ;; the file has changed on disk in the meantime, all we can do
420 ;; is offer to revert the whole thing. If you choose not to
421 ;; revert, then you might miss some output then happened
422 ;; between visiting the file and activating a-r-t-mode.
423 (and (zerop auto-revert-tail-pos)
424 (not (verify-visited-file-modtime (current-buffer)))
425 (y-or-n-p "File changed on disk, content may be missing. \
426 Perform a full revert? ")
427 ;; Use this (not just revert-buffer) for point-preservation.
428 (auto-revert-buffers))
429 ;; else we might reappend our own end when we save
430 (add-hook 'before-save-hook (lambda () (auto-revert-tail-mode 0)) nil t)
431 (or (local-variable-p 'auto-revert-tail-pos) ; don't lose prior position
432 (setq-local auto-revert-tail-pos
433 (nth 7 (file-attributes buffer-file-name))))
434 ;; let auto-revert-mode set up the mechanism for us if it isn't already
435 (or auto-revert-mode
436 (let ((auto-revert-tail-mode t))
437 (auto-revert-mode 1)))
438 (setq auto-revert-mode nil))))
439
440
441 ;;;###autoload
442 (defun turn-on-auto-revert-tail-mode ()
443 "Turn on Auto-Revert Tail Mode.
444
445 This function is designed to be added to hooks, for example:
446 (add-hook \\='my-logfile-mode-hook #\\='turn-on-auto-revert-tail-mode)"
447 (auto-revert-tail-mode 1))
448
449
450 ;;;###autoload
451 (define-minor-mode global-auto-revert-mode
452 "Toggle Global Auto-Revert Mode.
453 With a prefix argument ARG, enable Global Auto-Revert Mode if ARG
454 is positive, and disable it otherwise. If called from Lisp,
455 enable the mode if ARG is omitted or nil.
456
457 Global Auto-Revert Mode is a global minor mode that reverts any
458 buffer associated with a file when the file changes on disk. Use
459 `auto-revert-mode' to revert a particular buffer.
460
461 If `global-auto-revert-non-file-buffers' is non-nil, this mode
462 may also revert some non-file buffers, as described in the
463 documentation of that variable. It ignores buffers with modes
464 matching `global-auto-revert-ignore-modes', and buffers with a
465 non-nil vale of `global-auto-revert-ignore-buffer'.
466
467 This function calls the hook `global-auto-revert-mode-hook'.
468 It displays the text that `global-auto-revert-mode-text'
469 specifies in the mode line."
470 :global t :group 'auto-revert :lighter global-auto-revert-mode-text
471 (auto-revert-set-timer)
472 (if global-auto-revert-mode
473 (auto-revert-buffers)
474 (dolist (buf (buffer-list))
475 (with-current-buffer buf
476 (when auto-revert-use-notify
477 (auto-revert-notify-rm-watch))))))
478
479 (defun auto-revert-set-timer ()
480 "Restart or cancel the timer used by Auto-Revert Mode.
481 If such a timer is active, cancel it. Start a new timer if
482 Global Auto-Revert Mode is active or if Auto-Revert Mode is active
483 in some buffer. Restarting the timer ensures that Auto-Revert Mode
484 will use an up-to-date value of `auto-revert-interval'"
485 (interactive)
486 (if (timerp auto-revert-timer)
487 (cancel-timer auto-revert-timer))
488 (setq auto-revert-timer
489 (if (or global-auto-revert-mode auto-revert-buffer-list)
490 (run-with-timer auto-revert-interval
491 auto-revert-interval
492 'auto-revert-buffers))))
493
494 (defun auto-revert-notify-rm-watch ()
495 "Disable file notification for current buffer's associated file."
496 (when auto-revert-notify-watch-descriptor
497 (maphash
498 (lambda (key value)
499 (when (equal key auto-revert-notify-watch-descriptor)
500 (setq value (delete (current-buffer) value))
501 (if value
502 (puthash key value auto-revert-notify-watch-descriptor-hash-list)
503 (remhash key auto-revert-notify-watch-descriptor-hash-list)
504 (ignore-errors
505 (file-notify-rm-watch auto-revert-notify-watch-descriptor)))))
506 auto-revert-notify-watch-descriptor-hash-list)
507 (remove-hook 'kill-buffer-hook #'auto-revert-notify-rm-watch))
508 (setq auto-revert-notify-watch-descriptor nil
509 auto-revert-notify-modified-p nil))
510
511 (defun auto-revert-notify-add-watch ()
512 "Enable file notification for current buffer's associated file."
513 ;; We can assume that `buffer-file-name' and
514 ;; `auto-revert-use-notify' are non-nil.
515 (if (or (string-match auto-revert-notify-exclude-dir-regexp
516 (expand-file-name default-directory))
517 (file-symlink-p (or buffer-file-name default-directory)))
518
519 ;; Fallback to file checks.
520 (setq-local auto-revert-use-notify nil)
521
522 (when (not auto-revert-notify-watch-descriptor)
523 (setq auto-revert-notify-watch-descriptor
524 (ignore-errors
525 (if buffer-file-name
526 (file-notify-add-watch
527 (expand-file-name buffer-file-name default-directory)
528 '(change attribute-change)
529 'auto-revert-notify-handler)
530 (file-notify-add-watch
531 (expand-file-name default-directory)
532 '(change)
533 'auto-revert-notify-handler))))
534 (if auto-revert-notify-watch-descriptor
535 (progn
536 (puthash
537 auto-revert-notify-watch-descriptor
538 (cons (current-buffer)
539 (gethash auto-revert-notify-watch-descriptor
540 auto-revert-notify-watch-descriptor-hash-list))
541 auto-revert-notify-watch-descriptor-hash-list)
542 (add-hook 'kill-buffer-hook
543 #'auto-revert-notify-rm-watch nil t))
544 ;; Fallback to file checks.
545 (setq-local auto-revert-use-notify nil)))))
546
547 ;; If we have file notifications, we want to update the auto-revert buffers
548 ;; immediately when a notification occurs. Since file updates can happen very
549 ;; often, we want to skip some revert operations so that we don't spend all our
550 ;; time reverting the buffer.
551 ;;
552 ;; We do this by reverting immediately in response to the first in a flurry of
553 ;; notifications. We suppress subsequent notifications until the next time
554 ;; `auto-revert-buffers' is called (this happens on a timer with a period set by
555 ;; `auto-revert-interval').
556 (defvar auto-revert-buffers-counter 1
557 "Incremented each time `auto-revert-buffers' is called")
558 (defvar-local auto-revert-buffers-counter-lockedout 0
559 "Buffer-local value to indicate whether we should immediately
560 update the buffer on a notification event or not. If
561
562 (= auto-revert-buffers-counter-lockedout
563 auto-revert-buffers-counter)
564
565 then the updates are locked out, and we wait until the next call
566 of `auto-revert-buffers' to revert the buffer. If no lockout is
567 present, then we revert immediately and set the lockout, so that
568 no more reverts are possible until the next call of
569 `auto-revert-buffers'")
570
571 (defun auto-revert-notify-handler (event)
572 "Handle an EVENT returned from file notification."
573 (with-demoted-errors
574 (let* ((descriptor (car event))
575 (action (nth 1 event))
576 (file (nth 2 event))
577 (file1 (nth 3 event)) ;; Target of `renamed'.
578 (buffers (gethash descriptor
579 auto-revert-notify-watch-descriptor-hash-list)))
580 ;; Check, that event is meant for us.
581 (cl-assert descriptor)
582 ;; Since we watch a directory, a file name must be returned.
583 (cl-assert (stringp file))
584 (when (eq action 'renamed) (cl-assert (stringp file1)))
585
586 (if (eq action 'stopped)
587 ;; File notification has stopped. Continue with polling.
588 (cl-dolist (buffer
589 (if global-auto-revert-mode
590 (buffer-list) auto-revert-buffer-list))
591 (with-current-buffer buffer
592 (when (and (equal descriptor auto-revert-notify-watch-descriptor)
593 (or
594 ;; A buffer associated with a file.
595 (and (stringp buffer-file-name)
596 (string-equal
597 (file-name-nondirectory file)
598 (file-name-nondirectory buffer-file-name)))
599 ;; A buffer w/o a file, like dired.
600 (null buffer-file-name)))
601 (auto-revert-notify-rm-watch)
602 (setq-local auto-revert-use-notify nil))))
603
604 ;; Loop over all buffers, in order to find the intended one.
605 (cl-dolist (buffer buffers)
606 (when (buffer-live-p buffer)
607 (with-current-buffer buffer
608 (when (or
609 ;; A buffer associated with a file.
610 (and (stringp buffer-file-name)
611 (or
612 (and (memq
613 action '(attribute-changed changed created))
614 (string-equal
615 (file-name-nondirectory file)
616 (file-name-nondirectory buffer-file-name)))
617 (and (eq action 'renamed)
618 (string-equal
619 (file-name-nondirectory file1)
620 (file-name-nondirectory buffer-file-name)))))
621 ;; A buffer w/o a file, like dired.
622 (and (null buffer-file-name)
623 (memq action '(created renamed deleted))))
624 ;; Mark buffer modified.
625 (setq auto-revert-notify-modified-p t)
626
627 ;; Revert the buffer now if we're not locked out.
628 (when (/= auto-revert-buffers-counter-lockedout
629 auto-revert-buffers-counter)
630 (auto-revert-handler)
631 (setq auto-revert-buffers-counter-lockedout
632 auto-revert-buffers-counter))
633
634 ;; No need to check other buffers.
635 (cl-return)))))))))
636
637 (defun auto-revert-active-p ()
638 "Check if auto-revert is active (in current buffer or globally)."
639 (or auto-revert-mode
640 auto-revert-tail-mode
641 (and
642 global-auto-revert-mode
643 (not global-auto-revert-ignore-buffer)
644 (not (memq major-mode
645 global-auto-revert-ignore-modes)))))
646
647 (defun auto-revert-handler ()
648 "Revert current buffer, if appropriate.
649 This is an internal function used by Auto-Revert Mode."
650 (let* ((buffer (current-buffer)) size
651 ;; Tramp caches the file attributes. Setting
652 ;; `remote-file-name-inhibit-cache' forces Tramp to reread
653 ;; the values.
654 (remote-file-name-inhibit-cache t)
655 (revert
656 (if buffer-file-name
657 (and (or auto-revert-remote-files
658 (not (file-remote-p buffer-file-name)))
659 (or (not auto-revert-use-notify)
660 auto-revert-notify-modified-p)
661 (if auto-revert-tail-mode
662 (and (file-readable-p buffer-file-name)
663 (/= auto-revert-tail-pos
664 (setq size
665 (nth 7 (file-attributes
666 buffer-file-name)))))
667 (funcall (or buffer-stale-function
668 #'buffer-stale--default-function)
669 t)))
670 (and (or auto-revert-mode
671 global-auto-revert-non-file-buffers)
672 (funcall (or buffer-stale-function
673 #'buffer-stale--default-function)
674 t))))
675 eob eoblist)
676 (setq auto-revert-notify-modified-p nil)
677 (when revert
678 (when (and auto-revert-verbose
679 (not (eq revert 'fast)))
680 (message "Reverting buffer `%s'." (buffer-name)))
681 ;; If point (or a window point) is at the end of the buffer, we
682 ;; want to keep it at the end after reverting. This allows one
683 ;; to tail a file.
684 (when buffer-file-name
685 (setq eob (eobp))
686 (walk-windows
687 (lambda (window)
688 (and (eq (window-buffer window) buffer)
689 (= (window-point window) (point-max))
690 (push window eoblist)))
691 'no-mini t))
692 (if auto-revert-tail-mode
693 (auto-revert-tail-handler size)
694 ;; Bind buffer-read-only in case user has done C-x C-q, so as
695 ;; not to forget that. This gives undesirable results when
696 ;; the file's mode changes, but that is less common.
697 (let ((buffer-read-only buffer-read-only))
698 ;; Bug#23276: When the file has been deleted, keep the
699 ;; buffer unchanged.
700 (ignore-errors
701 (revert-buffer 'ignore-auto 'dont-ask 'preserve-modes))))
702 (when buffer-file-name
703 (when eob (goto-char (point-max)))
704 (dolist (window eoblist)
705 (set-window-point window (point-max)))))
706 ;; `preserve-modes' avoids changing the (minor) modes. But we do
707 ;; want to reset the mode for VC, so we do it manually.
708 (when (or revert auto-revert-check-vc-info)
709 (vc-refresh-state))))
710
711 (defun auto-revert-tail-handler (size)
712 (let ((modified (buffer-modified-p))
713 (inhibit-read-only t) ; Ignore.
714 (file buffer-file-name)
715 (buffer-file-name nil)) ; Ignore that file has changed.
716 (when (/= auto-revert-tail-pos size)
717 (run-hooks 'before-revert-hook)
718 (undo-boundary)
719 (save-restriction
720 (widen)
721 (save-excursion
722 (goto-char (point-max))
723 (insert-file-contents file nil
724 (and (< auto-revert-tail-pos size)
725 auto-revert-tail-pos)
726 size)))
727 (run-hooks 'after-revert-hook)
728 (undo-boundary)
729 (setq auto-revert-tail-pos size)
730 (restore-buffer-modified-p modified)))
731 (set-visited-file-modtime))
732
733 (defun auto-revert-buffers ()
734 "Revert buffers as specified by Auto-Revert and Global Auto-Revert Mode.
735
736 Should `global-auto-revert-mode' be active all file buffers are checked.
737
738 Should `auto-revert-mode' be active in some buffers, those buffers
739 are checked.
740
741 Non-file buffers that have a custom `revert-buffer-function' and
742 `buffer-stale-function' are reverted either when Auto-Revert
743 Mode is active in that buffer, or when the variable
744 `global-auto-revert-non-file-buffers' is non-nil and Global
745 Auto-Revert Mode is active.
746
747 This function stops whenever there is user input. The buffers not
748 checked are stored in the variable `auto-revert-remaining-buffers'.
749
750 To avoid starvation, the buffers in `auto-revert-remaining-buffers'
751 are checked first the next time this function is called.
752
753 This function is also responsible for removing buffers no longer in
754 Auto-Revert Mode from `auto-revert-buffer-list', and for canceling
755 the timer when no buffers need to be checked."
756
757 (setq auto-revert-buffers-counter
758 (1+ auto-revert-buffers-counter))
759
760 (save-match-data
761 (let ((bufs (if global-auto-revert-mode
762 (buffer-list)
763 auto-revert-buffer-list))
764 remaining new)
765 ;; Partition `bufs' into two halves depending on whether or not
766 ;; the buffers are in `auto-revert-remaining-buffers'. The two
767 ;; halves are then re-joined with the "remaining" buffers at the
768 ;; head of the list.
769 (dolist (buf auto-revert-remaining-buffers)
770 (if (memq buf bufs)
771 (push buf remaining)))
772 (dolist (buf bufs)
773 (if (not (memq buf remaining))
774 (push buf new)))
775 (setq bufs (nreverse (nconc new remaining)))
776 (while (and bufs
777 (not (and auto-revert-stop-on-user-input
778 (input-pending-p))))
779 (let ((buf (car bufs)))
780 (if (buffer-live-p buf)
781 (with-current-buffer buf
782 ;; Test if someone has turned off Auto-Revert Mode in a
783 ;; non-standard way, for example by changing major mode.
784 (if (and (not auto-revert-mode)
785 (not auto-revert-tail-mode)
786 (memq buf auto-revert-buffer-list))
787 (setq auto-revert-buffer-list
788 (delq buf auto-revert-buffer-list)))
789 (when (auto-revert-active-p)
790 ;; Enable file notification.
791 (when (and auto-revert-use-notify
792 (not auto-revert-notify-watch-descriptor))
793 (auto-revert-notify-add-watch))
794 (auto-revert-handler)))
795 ;; Remove dead buffer from `auto-revert-buffer-list'.
796 (setq auto-revert-buffer-list
797 (delq buf auto-revert-buffer-list))))
798 (setq bufs (cdr bufs)))
799 (setq auto-revert-remaining-buffers bufs)
800 ;; Check if we should cancel the timer.
801 (when (and (not global-auto-revert-mode)
802 (null auto-revert-buffer-list))
803 (cancel-timer auto-revert-timer)
804 (setq auto-revert-timer nil)))))
805
806
807 ;; The end:
808 (provide 'autorevert)
809
810 (run-hooks 'auto-revert-load-hook)
811
812 ;;; autorevert.el ends here