62 |
|
|
63 |
;; Usage: |
;; Usage: |
64 |
;; |
;; |
65 |
;; Go to the appropriate buffer and press: |
;; Go to the appropriate buffer and press either of: |
66 |
;; M-x auto-revert-mode RET |
;; M-x auto-revert-mode RET |
67 |
|
;; M-x auto-revert-tail-mode RET |
68 |
;; |
;; |
69 |
;; To activate Global Auto-Revert Mode, press: |
;; To activate Global Auto-Revert Mode, press: |
70 |
;; M-x global-auto-revert-mode RET |
;; M-x global-auto-revert-mode RET |
106 |
|
|
107 |
;; Variables: |
;; Variables: |
108 |
|
|
109 |
;; Autoload for the benefit of `make-mode-line-mouse-sensitive'. |
;;; What's this?: ;; Autoload for the benefit of `make-mode-line-mouse-sensitive'. |
110 |
;;;###autoload |
;;; What's this?: ;;;###autoload |
111 |
(defvar auto-revert-mode nil |
(defvar auto-revert-mode nil |
112 |
"*Non-nil when Auto-Revert Mode is active. |
"*Non-nil when Auto-Revert Mode is active. |
113 |
Never set this variable directly, use the command `auto-revert-mode' instead.") |
Never set this variable directly, use the command `auto-revert-mode' instead.") |
114 |
(put 'auto-revert-mode 'permanent-local t) |
(put 'auto-revert-mode 'permanent-local t) |
115 |
|
|
116 |
|
(defvar auto-revert-tail-mode nil |
117 |
|
"*Non-nil when Auto-Revert Tail Mode is active. |
118 |
|
Never set this variable directly, use the command `auto-revert-mode' instead.") |
119 |
|
(put 'auto-revert-tail-mode 'permanent-local t) |
120 |
|
|
121 |
(defvar auto-revert-timer nil |
(defvar auto-revert-timer nil |
122 |
"Timer used by Auto-Revert Mode.") |
"Timer used by Auto-Revert Mode.") |
123 |
|
|
159 |
:group 'auto-revert |
:group 'auto-revert |
160 |
:type 'string) |
:type 'string) |
161 |
|
|
162 |
|
(defcustom auto-revert-tail-mode-text " Tail" |
163 |
|
"String to display in the mode line when Auto-Revert Tail Mode is active. |
164 |
|
|
165 |
|
\(When the string is not empty, make sure that it has a leading space.)" |
166 |
|
:group 'auto-revert |
167 |
|
:type 'string) |
168 |
|
|
169 |
(defcustom auto-revert-mode-hook nil |
(defcustom auto-revert-mode-hook nil |
170 |
"Functions to run when Auto-Revert Mode is activated." |
"Functions to run when Auto-Revert Mode is activated." |
171 |
:tag "Auto Revert Mode Hook" ; To separate it from `global-...' |
:tag "Auto Revert Mode Hook" ; To separate it from `global-...' |
203 |
:type 'boolean |
:type 'boolean |
204 |
:link '(info-link "(emacs-xtra)Autorevert")) |
:link '(info-link "(emacs-xtra)Autorevert")) |
205 |
|
|
206 |
(defcustom global-auto-revert-ignore-modes '() |
(defcustom global-auto-revert-ignore-modes () |
207 |
"List of major modes Global Auto-Revert Mode should not check." |
"List of major modes Global Auto-Revert Mode should not check." |
208 |
:group 'auto-revert |
:group 'auto-revert |
209 |
:type '(repeat sexp)) |
:type '(repeat sexp)) |
243 |
|
|
244 |
;; Internal variables: |
;; Internal variables: |
245 |
|
|
246 |
(defvar auto-revert-buffer-list '() |
(defvar auto-revert-buffer-list () |
247 |
"List of buffers in Auto-Revert Mode. |
"List of buffers in Auto-Revert Mode. |
248 |
|
|
249 |
Note that only Auto-Revert Mode, never Global Auto-Revert Mode, adds |
Note that only Auto-Revert Mode, never Global Auto-Revert Mode, adds |
252 |
The timer function `auto-revert-buffers' is responsible for purging |
The timer function `auto-revert-buffers' is responsible for purging |
253 |
the list of old buffers.") |
the list of old buffers.") |
254 |
|
|
255 |
(defvar auto-revert-remaining-buffers '() |
(defvar auto-revert-remaining-buffers () |
256 |
"Buffers not checked when user input stopped execution.") |
"Buffers not checked when user input stopped execution.") |
257 |
|
|
258 |
|
(defvar auto-revert-tail-pos 0 |
259 |
|
"Position of last known end of file.") |
260 |
|
|
261 |
|
(add-hook 'find-file-hook |
262 |
|
(lambda () |
263 |
|
(set (make-local-variable 'auto-revert-tail-pos) |
264 |
|
(save-restriction (widen) (1- (point-max)))))) |
265 |
|
|
266 |
;; Functions: |
;; Functions: |
267 |
|
|
271 |
|
|
272 |
With arg, turn Auto Revert mode on if and only if arg is positive. |
With arg, turn Auto Revert mode on if and only if arg is positive. |
273 |
This is a minor mode that affects only the current buffer. |
This is a minor mode that affects only the current buffer. |
274 |
Use `global-auto-revert-mode' to automatically revert all buffers." |
Use `global-auto-revert-mode' to automatically revert all buffers. |
275 |
|
Use `auto-revert-tail-mode' if you know that the file will only grow |
276 |
|
without being changed in the part that is already in the buffer." |
277 |
nil auto-revert-mode-text nil |
nil auto-revert-mode-text nil |
278 |
(if auto-revert-mode |
(if auto-revert-mode |
279 |
(if (not (memq (current-buffer) auto-revert-buffer-list)) |
(if (not (memq (current-buffer) auto-revert-buffer-list)) |
282 |
(delq (current-buffer) auto-revert-buffer-list))) |
(delq (current-buffer) auto-revert-buffer-list))) |
283 |
(auto-revert-set-timer) |
(auto-revert-set-timer) |
284 |
(when auto-revert-mode |
(when auto-revert-mode |
285 |
(auto-revert-buffers))) |
(auto-revert-buffers) |
286 |
|
(setq auto-revert-tail-mode nil))) |
287 |
|
|
288 |
|
|
289 |
;;;###autoload |
;;;###autoload |
296 |
|
|
297 |
|
|
298 |
;;;###autoload |
;;;###autoload |
299 |
|
(define-minor-mode auto-revert-tail-mode |
300 |
|
"Toggle reverting tail of buffer when file on disk grows. |
301 |
|
With arg, turn Tail mode on iff arg is positive. |
302 |
|
|
303 |
|
When Tail mode is enabled, the tail of the file is constantly |
304 |
|
followed, as with the shell command `tail -f'. This means that |
305 |
|
whenever the file grows on disk (presumably because some |
306 |
|
background process is appending to it from time to time), this is |
307 |
|
reflected in the current buffer. |
308 |
|
|
309 |
|
You can edit the buffer and turn this mode off and on again as |
310 |
|
you please. But make sure the background process has stopped |
311 |
|
writing before you save the file! |
312 |
|
|
313 |
|
Use `auto-revert-mode' for changes other than appends!" |
314 |
|
:group 'find-file :lighter auto-revert-tail-mode-text |
315 |
|
(when auto-revert-tail-mode |
316 |
|
(unless buffer-file-name |
317 |
|
(auto-revert-tail-mode 0) |
318 |
|
(error "This buffer is not visiting a file")) |
319 |
|
(if (and (buffer-modified-p) |
320 |
|
(not auto-revert-tail-pos) ; library was loaded only after finding file |
321 |
|
(not (y-or-n-p "Buffer is modified, so tail offset may be wrong. Proceed? "))) |
322 |
|
(auto-revert-tail-mode 0) |
323 |
|
;; else we might reappend our own end when we save |
324 |
|
(add-hook 'before-save-hook (lambda () (auto-revert-tail-mode 0)) nil t) |
325 |
|
(or (local-variable-p 'auto-revert-tail-pos) ; don't lose prior position |
326 |
|
(set (make-variable-buffer-local 'auto-revert-tail-pos) |
327 |
|
(save-restriction (widen) (1- (point-max))))) |
328 |
|
;; let auto-revert-mode set up the mechanism for us if it isn't already |
329 |
|
(or auto-revert-mode |
330 |
|
(let ((auto-revert-tail-mode t)) |
331 |
|
(auto-revert-mode 1))) |
332 |
|
(setq auto-revert-mode nil)))) |
333 |
|
|
334 |
|
|
335 |
|
;;;###autoload |
336 |
|
(defun turn-on-auto-revert-tail-mode () |
337 |
|
"Turn on Auto-Revert Tail Mode. |
338 |
|
|
339 |
|
This function is designed to be added to hooks, for example: |
340 |
|
(add-hook 'my-logfile-mode-hook 'turn-on-auto-revert-tail-mode)" |
341 |
|
(auto-revert-tail-mode 1)) |
342 |
|
|
343 |
|
|
344 |
|
;;;###autoload |
345 |
(define-minor-mode global-auto-revert-mode |
(define-minor-mode global-auto-revert-mode |
346 |
"Revert any buffer when file on disk changes. |
"Revert any buffer when file on disk changes. |
347 |
|
|
367 |
(if (or global-auto-revert-mode auto-revert-buffer-list) |
(if (or global-auto-revert-mode auto-revert-buffer-list) |
368 |
(run-with-timer auto-revert-interval |
(run-with-timer auto-revert-interval |
369 |
auto-revert-interval |
auto-revert-interval |
370 |
'auto-revert-buffers) |
'auto-revert-buffers)))) |
|
nil))) |
|
371 |
|
|
372 |
(defun auto-revert-active-p () |
(defun auto-revert-active-p () |
373 |
"Check if auto-revert is active (in current buffer or globally)." |
"Check if auto-revert is active (in current buffer or globally)." |
374 |
(or auto-revert-mode |
(or auto-revert-mode |
375 |
|
auto-revert-tail-mode |
376 |
(and |
(and |
377 |
global-auto-revert-mode |
global-auto-revert-mode |
378 |
(not global-auto-revert-ignore-buffer) |
(not global-auto-revert-ignore-buffer) |
382 |
(defun auto-revert-handler () |
(defun auto-revert-handler () |
383 |
"Revert current buffer, if appropriate. |
"Revert current buffer, if appropriate. |
384 |
This is an internal function used by Auto-Revert Mode." |
This is an internal function used by Auto-Revert Mode." |
385 |
(unless (buffer-modified-p) |
(when (or auto-revert-tail-mode (not (buffer-modified-p))) |
386 |
(let ((buffer (current-buffer)) revert eob eoblist) |
(let* ((buffer (current-buffer)) |
387 |
(or (and buffer-file-name |
(revert |
388 |
(not (file-remote-p buffer-file-name)) |
(or (and buffer-file-name |
389 |
(file-readable-p buffer-file-name) |
(not (file-remote-p buffer-file-name)) |
390 |
(not (verify-visited-file-modtime buffer)) |
(file-readable-p buffer-file-name) |
391 |
(setq revert t)) |
(not (verify-visited-file-modtime buffer))) |
392 |
(and (or auto-revert-mode global-auto-revert-non-file-buffers) |
(and (or auto-revert-mode auto-revert-tail-mode |
393 |
revert-buffer-function |
global-auto-revert-non-file-buffers) |
394 |
(boundp 'buffer-stale-function) |
revert-buffer-function |
395 |
(functionp buffer-stale-function) |
(boundp 'buffer-stale-function) |
396 |
(setq revert (funcall buffer-stale-function t)))) |
(functionp buffer-stale-function) |
397 |
|
(funcall buffer-stale-function t)))) |
398 |
|
eob eoblist) |
399 |
(when revert |
(when revert |
400 |
(when (and auto-revert-verbose |
(when (and auto-revert-verbose |
401 |
(not (eq revert 'fast))) |
(not (eq revert 'fast))) |
411 |
(= (window-point window) (point-max)) |
(= (window-point window) (point-max)) |
412 |
(push window eoblist))) |
(push window eoblist))) |
413 |
'no-mini t)) |
'no-mini t)) |
414 |
(revert-buffer 'ignore-auto 'dont-ask 'preserve-modes) |
(if auto-revert-tail-mode |
415 |
|
(auto-revert-tail-handler) |
416 |
|
(revert-buffer 'ignore-auto 'dont-ask 'preserve-modes)) |
417 |
(when buffer-file-name |
(when buffer-file-name |
418 |
(when eob (goto-char (point-max))) |
(when eob (goto-char (point-max))) |
419 |
(dolist (window eoblist) |
(dolist (window eoblist) |
423 |
(when (or revert auto-revert-check-vc-info) |
(when (or revert auto-revert-check-vc-info) |
424 |
(vc-find-file-hook))))) |
(vc-find-file-hook))))) |
425 |
|
|
426 |
|
(defun auto-revert-tail-handler () |
427 |
|
(let ((size (nth 7 (file-attributes buffer-file-name))) |
428 |
|
(modified (buffer-modified-p)) |
429 |
|
buffer-read-only ; ignore |
430 |
|
(file buffer-file-name) |
431 |
|
buffer-file-name) ; ignore that file has changed |
432 |
|
(when (> size auto-revert-tail-pos) |
433 |
|
(save-restriction |
434 |
|
(widen) |
435 |
|
(save-excursion |
436 |
|
(goto-char (point-max)) |
437 |
|
(insert-file-contents file nil auto-revert-tail-pos size))) |
438 |
|
(setq auto-revert-tail-pos size) |
439 |
|
(set-buffer-modified-p modified))) |
440 |
|
(set-visited-file-modtime)) |
441 |
|
|
442 |
(defun auto-revert-buffers () |
(defun auto-revert-buffers () |
443 |
"Revert buffers as specified by Auto-Revert and Global Auto-Revert Mode. |
"Revert buffers as specified by Auto-Revert and Global Auto-Revert Mode. |
444 |
|
|
465 |
(let ((bufs (if global-auto-revert-mode |
(let ((bufs (if global-auto-revert-mode |
466 |
(buffer-list) |
(buffer-list) |
467 |
auto-revert-buffer-list)) |
auto-revert-buffer-list)) |
468 |
(remaining '()) |
(remaining ()) |
469 |
(new '())) |
(new ())) |
470 |
;; Partition `bufs' into two halves depending on whether or not |
;; Partition `bufs' into two halves depending on whether or not |
471 |
;; the buffers are in `auto-revert-remaining-buffers'. The two |
;; the buffers are in `auto-revert-remaining-buffers'. The two |
472 |
;; halves are then re-joined with the "remaining" buffers at the |
;; halves are then re-joined with the "remaining" buffers at the |
487 |
;; Test if someone has turned off Auto-Revert Mode in a |
;; Test if someone has turned off Auto-Revert Mode in a |
488 |
;; non-standard way, for example by changing major mode. |
;; non-standard way, for example by changing major mode. |
489 |
(if (and (not auto-revert-mode) |
(if (and (not auto-revert-mode) |
490 |
|
(not auto-revert-tail-mode) |
491 |
(memq buf auto-revert-buffer-list)) |
(memq buf auto-revert-buffer-list)) |
492 |
(setq auto-revert-buffer-list |
(setq auto-revert-buffer-list |
493 |
(delq buf auto-revert-buffer-list))) |
(delq buf auto-revert-buffer-list))) |