diff options
| author | Daniel Pfeiffer | 2004-07-14 21:06:39 +0000 |
|---|---|---|
| committer | Daniel Pfeiffer | 2004-07-14 21:06:39 +0000 |
| commit | dddc748bec10c86dcb6f93e8f90dd318e93c13a0 (patch) | |
| tree | 307dddfc21f24cdeba0c901b30d20276f1db3611 | |
| parent | d5c24489bda23bc04e39261f56c05837ecb89e12 (diff) | |
| download | emacs-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.el | 140 |
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. |
| 112 | Never set this variable directly, use the command `auto-revert-mode' instead.") | 113 | Never 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. | ||
| 118 | Never 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 | ||
| 236 | Note that only Auto-Revert Mode, never Global Auto-Revert Mode, adds | 249 | Note that only Auto-Revert Mode, never Global Auto-Revert Mode, adds |
| @@ -239,9 +252,16 @@ buffers to this list. | |||
| 239 | The timer function `auto-revert-buffers' is responsible for purging | 252 | The timer function `auto-revert-buffers' is responsible for purging |
| 240 | the list of old buffers.") | 253 | the 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 | ||
| 252 | With arg, turn Auto Revert mode on if and only if arg is positive. | 272 | With arg, turn Auto Revert mode on if and only if arg is positive. |
| 253 | This is a minor mode that affects only the current buffer. | 273 | This is a minor mode that affects only the current buffer. |
| 254 | Use `global-auto-revert-mode' to automatically revert all buffers." | 274 | 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." | ||
| 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. | ||
| 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 | ||
| 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. |
| 315 | This is an internal function used by Auto-Revert Mode." | 384 | This 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))) |