aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Pfeiffer2004-07-14 21:06:39 +0000
committerDaniel Pfeiffer2004-07-14 21:06:39 +0000
commitdddc748bec10c86dcb6f93e8f90dd318e93c13a0 (patch)
tree307dddfc21f24cdeba0c901b30d20276f1db3611
parentd5c24489bda23bc04e39261f56c05837ecb89e12 (diff)
downloademacs-dddc748bec10c86dcb6f93e8f90dd318e93c13a0.tar.gz
emacs-dddc748bec10c86dcb6f93e8f90dd318e93c13a0.zip
(auto-revert-tail-mode, auto-revert-tail-mode-text, auto-revert-tail-pos): New vars.
(auto-revert-mode): Turn off auto-revert-tail-mode, so we're not in both at the same time. (auto-revert-tail-mode): New command. (turn-on-auto-revert-tail-mode, auto-revert-tail-handler): New funs. (auto-revert-handler): Revert only either tail or whole file.
-rw-r--r--lisp/autorevert.el140
1 files changed, 115 insertions, 25 deletions
diff --git a/lisp/autorevert.el b/lisp/autorevert.el
index 7b786882cf6..596c7ff8997 100644
--- a/lisp/autorevert.el
+++ b/lisp/autorevert.el
@@ -62,8 +62,9 @@
62 62
63;; Usage: 63;; Usage:
64;; 64;;
65;; Go to the appropriate buffer and press: 65;; Go to the appropriate buffer and press either of:
66;; M-x auto-revert-mode RET 66;; M-x auto-revert-mode RET
67;; M-x auto-revert-tail-mode RET
67;; 68;;
68;; To activate Global Auto-Revert Mode, press: 69;; To activate Global Auto-Revert Mode, press:
69;; M-x global-auto-revert-mode RET 70;; M-x global-auto-revert-mode RET
@@ -105,13 +106,18 @@ Global Auto-Revert Mode applies to all buffers."
105 106
106;; Variables: 107;; Variables:
107 108
108;; Autoload for the benefit of `make-mode-line-mouse-sensitive'. 109;;; What's this?: ;; Autoload for the benefit of `make-mode-line-mouse-sensitive'.
109;;;###autoload 110;;; What's this?: ;;;###autoload
110(defvar auto-revert-mode nil 111(defvar auto-revert-mode nil
111 "*Non-nil when Auto-Revert Mode is active. 112 "*Non-nil when Auto-Revert Mode is active.
112Never set this variable directly, use the command `auto-revert-mode' instead.") 113Never set this variable directly, use the command `auto-revert-mode' instead.")
113(put 'auto-revert-mode 'permanent-local t) 114(put 'auto-revert-mode 'permanent-local t)
114 115
116(defvar auto-revert-tail-mode nil
117 "*Non-nil when Auto-Revert Tail Mode is active.
118Never set this variable directly, use the command `auto-revert-mode' instead.")
119(put 'auto-revert-tail-mode 'permanent-local t)
120
115(defvar auto-revert-timer nil 121(defvar auto-revert-timer nil
116 "Timer used by Auto-Revert Mode.") 122 "Timer used by Auto-Revert Mode.")
117 123
@@ -153,6 +159,13 @@ When non-nil, a message is generated whenever a file is reverted."
153 :group 'auto-revert 159 :group 'auto-revert
154 :type 'string) 160 :type 'string)
155 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
156(defcustom auto-revert-mode-hook nil 169(defcustom auto-revert-mode-hook nil
157 "Functions to run when Auto-Revert Mode is activated." 170 "Functions to run when Auto-Revert Mode is activated."
158 :tag "Auto Revert Mode Hook" ; To separate it from `global-...' 171 :tag "Auto Revert Mode Hook" ; To separate it from `global-...'
@@ -190,7 +203,7 @@ For more information, see Info node `(emacs-xtra)Autorevert'."
190 :type 'boolean 203 :type 'boolean
191 :link '(info-link "(emacs-xtra)Autorevert")) 204 :link '(info-link "(emacs-xtra)Autorevert"))
192 205
193(defcustom global-auto-revert-ignore-modes '() 206(defcustom global-auto-revert-ignore-modes ()
194 "List of major modes Global Auto-Revert Mode should not check." 207 "List of major modes Global Auto-Revert Mode should not check."
195 :group 'auto-revert 208 :group 'auto-revert
196 :type '(repeat sexp)) 209 :type '(repeat sexp))
@@ -230,7 +243,7 @@ This variable becomes buffer local when set in any fashion.")
230 243
231;; Internal variables: 244;; Internal variables:
232 245
233(defvar auto-revert-buffer-list '() 246(defvar auto-revert-buffer-list ()
234 "List of buffers in Auto-Revert Mode. 247 "List of buffers in Auto-Revert Mode.
235 248
236Note that only Auto-Revert Mode, never Global Auto-Revert Mode, adds 249Note that only Auto-Revert Mode, never Global Auto-Revert Mode, adds
@@ -239,9 +252,16 @@ buffers to this list.
239The timer function `auto-revert-buffers' is responsible for purging 252The timer function `auto-revert-buffers' is responsible for purging
240the list of old buffers.") 253the list of old buffers.")
241 254
242(defvar auto-revert-remaining-buffers '() 255(defvar auto-revert-remaining-buffers ()
243 "Buffers not checked when user input stopped execution.") 256 "Buffers not checked when user input stopped execution.")
244 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))))))
245 265
246;; Functions: 266;; Functions:
247 267
@@ -251,7 +271,9 @@ the list of old buffers.")
251 271
252With arg, turn Auto Revert mode on if and only if arg is positive. 272With arg, turn Auto Revert mode on if and only if arg is positive.
253This is a minor mode that affects only the current buffer. 273This is a minor mode that affects only the current buffer.
254Use `global-auto-revert-mode' to automatically revert all buffers." 274Use `global-auto-revert-mode' to automatically revert all buffers.
275Use `auto-revert-tail-mode' if you know that the file will only grow
276without being changed in the part that is already in the buffer."
255 nil auto-revert-mode-text nil 277 nil auto-revert-mode-text nil
256 (if auto-revert-mode 278 (if auto-revert-mode
257 (if (not (memq (current-buffer) auto-revert-buffer-list)) 279 (if (not (memq (current-buffer) auto-revert-buffer-list))
@@ -260,7 +282,8 @@ Use `global-auto-revert-mode' to automatically revert all buffers."
260 (delq (current-buffer) auto-revert-buffer-list))) 282 (delq (current-buffer) auto-revert-buffer-list)))
261 (auto-revert-set-timer) 283 (auto-revert-set-timer)
262 (when auto-revert-mode 284 (when auto-revert-mode
263 (auto-revert-buffers))) 285 (auto-revert-buffers)
286 (setq auto-revert-tail-mode nil)))
264 287
265 288
266;;;###autoload 289;;;###autoload
@@ -273,6 +296,52 @@ This function is designed to be added to hooks, for example:
273 296
274 297
275;;;###autoload 298;;;###autoload
299(define-minor-mode auto-revert-tail-mode
300 "Toggle reverting tail of buffer when file on disk grows.
301With arg, turn Tail mode on iff arg is positive.
302
303When Tail mode is enabled, the tail of the file is constantly
304followed, as with the shell command `tail -f'. This means that
305whenever the file grows on disk (presumably because some
306background process is appending to it from time to time), this is
307reflected in the current buffer.
308
309You can edit the buffer and turn this mode off and on again as
310you please. But make sure the background process has stopped
311writing before you save the file!
312
313Use `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
339This 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
276(define-minor-mode global-auto-revert-mode 345(define-minor-mode global-auto-revert-mode
277 "Revert any buffer when file on disk changes. 346 "Revert any buffer when file on disk changes.
278 347
@@ -298,12 +367,12 @@ will use an up-to-date value of `auto-revert-interval'"
298 (if (or global-auto-revert-mode auto-revert-buffer-list) 367 (if (or global-auto-revert-mode auto-revert-buffer-list)
299 (run-with-timer auto-revert-interval 368 (run-with-timer auto-revert-interval
300 auto-revert-interval 369 auto-revert-interval
301 'auto-revert-buffers) 370 'auto-revert-buffers))))
302 nil)))
303 371
304(defun auto-revert-active-p () 372(defun auto-revert-active-p ()
305 "Check if auto-revert is active (in current buffer or globally)." 373 "Check if auto-revert is active (in current buffer or globally)."
306 (or auto-revert-mode 374 (or auto-revert-mode
375 auto-revert-tail-mode
307 (and 376 (and
308 global-auto-revert-mode 377 global-auto-revert-mode
309 (not global-auto-revert-ignore-buffer) 378 (not global-auto-revert-ignore-buffer)
@@ -313,18 +382,20 @@ will use an up-to-date value of `auto-revert-interval'"
313(defun auto-revert-handler () 382(defun auto-revert-handler ()
314 "Revert current buffer, if appropriate. 383 "Revert current buffer, if appropriate.
315This is an internal function used by Auto-Revert Mode." 384This is an internal function used by Auto-Revert Mode."
316 (unless (buffer-modified-p) 385 (when (or auto-revert-tail-mode (not (buffer-modified-p)))
317 (let ((buffer (current-buffer)) revert eob eoblist) 386 (let* ((buffer (current-buffer))
318 (or (and buffer-file-name 387 (revert
319 (not (file-remote-p buffer-file-name)) 388 (or (and buffer-file-name
320 (file-readable-p buffer-file-name) 389 (not (file-remote-p buffer-file-name))
321 (not (verify-visited-file-modtime buffer)) 390 (file-readable-p buffer-file-name)
322 (setq revert t)) 391 (not (verify-visited-file-modtime buffer)))
323 (and (or auto-revert-mode global-auto-revert-non-file-buffers) 392 (and (or auto-revert-mode auto-revert-tail-mode
324 revert-buffer-function 393 global-auto-revert-non-file-buffers)
325 (boundp 'buffer-stale-function) 394 revert-buffer-function
326 (functionp buffer-stale-function) 395 (boundp 'buffer-stale-function)
327 (setq revert (funcall buffer-stale-function t)))) 396 (functionp buffer-stale-function)
397 (funcall buffer-stale-function t))))
398 eob eoblist)
328 (when revert 399 (when revert
329 (when (and auto-revert-verbose 400 (when (and auto-revert-verbose
330 (not (eq revert 'fast))) 401 (not (eq revert 'fast)))
@@ -340,7 +411,9 @@ This is an internal function used by Auto-Revert Mode."
340 (= (window-point window) (point-max)) 411 (= (window-point window) (point-max))
341 (push window eoblist))) 412 (push window eoblist)))
342 'no-mini t)) 413 'no-mini t))
343 (revert-buffer 'ignore-auto 'dont-ask 'preserve-modes) 414 (if auto-revert-tail-mode
415 (auto-revert-tail-handler)
416 (revert-buffer 'ignore-auto 'dont-ask 'preserve-modes))
344 (when buffer-file-name 417 (when buffer-file-name
345 (when eob (goto-char (point-max))) 418 (when eob (goto-char (point-max)))
346 (dolist (window eoblist) 419 (dolist (window eoblist)
@@ -350,6 +423,22 @@ This is an internal function used by Auto-Revert Mode."
350 (when (or revert auto-revert-check-vc-info) 423 (when (or revert auto-revert-check-vc-info)
351 (vc-find-file-hook))))) 424 (vc-find-file-hook)))))
352 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
353(defun auto-revert-buffers () 442(defun auto-revert-buffers ()
354 "Revert buffers as specified by Auto-Revert and Global Auto-Revert Mode. 443 "Revert buffers as specified by Auto-Revert and Global Auto-Revert Mode.
355 444
@@ -376,8 +465,8 @@ the timer when no buffers need to be checked."
376 (let ((bufs (if global-auto-revert-mode 465 (let ((bufs (if global-auto-revert-mode
377 (buffer-list) 466 (buffer-list)
378 auto-revert-buffer-list)) 467 auto-revert-buffer-list))
379 (remaining '()) 468 (remaining ())
380 (new '())) 469 (new ()))
381 ;; Partition `bufs' into two halves depending on whether or not 470 ;; Partition `bufs' into two halves depending on whether or not
382 ;; the buffers are in `auto-revert-remaining-buffers'. The two 471 ;; the buffers are in `auto-revert-remaining-buffers'. The two
383 ;; halves are then re-joined with the "remaining" buffers at the 472 ;; halves are then re-joined with the "remaining" buffers at the
@@ -398,6 +487,7 @@ the timer when no buffers need to be checked."
398 ;; Test if someone has turned off Auto-Revert Mode in a 487 ;; Test if someone has turned off Auto-Revert Mode in a
399 ;; non-standard way, for example by changing major mode. 488 ;; non-standard way, for example by changing major mode.
400 (if (and (not auto-revert-mode) 489 (if (and (not auto-revert-mode)
490 (not auto-revert-tail-mode)
401 (memq buf auto-revert-buffer-list)) 491 (memq buf auto-revert-buffer-list))
402 (setq auto-revert-buffer-list 492 (setq auto-revert-buffer-list
403 (delq buf auto-revert-buffer-list))) 493 (delq buf auto-revert-buffer-list)))