;;; autorevert.el --- revert buffers when files on disk change
-;; Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
+;; Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004,
+;; 2005 Free Software Foundation, Inc.
;; Author: Anders Lindgren <andersl@andersl.com>
;; Keywords: convenience
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
;;; Commentary:
;;
;; This package contains two minor modes: Global Auto-Revert Mode and
;; Auto-Revert Mode. Both modes automatically revert buffers
-;; whenever the corresponding files have been changed on disk.
+;; whenever the corresponding files have been changed on disk and the
+;; buffer contains no unsaved changes.
;;
;; Auto-Revert Mode can be activated for individual buffers. Global
;; Auto-Revert Mode applies to all file buffers. (If the user option
;; Just put point at the end of the buffer and it will stay there.
;; These rules apply to file buffers. For non-file buffers, the
;; behavior may be mode dependent.
+;;
+;; While you can use Auto Revert Mode to tail a file, this package
+;; contains a third minor mode, Auto Revert Tail Mode, which does so
+;; more efficiently, as long as you are sure that the file will only
+;; change by growing at the end. It only appends the new output,
+;; instead of reverting the entire buffer. It does so even if the
+;; buffer contains unsaved changes. (Because they will not be lost.)
;; Usage:
;;
(defvar auto-revert-tail-mode nil
"*Non-nil when Auto-Revert Tail Mode is active.
-Never set this variable directly, use the command `auto-revert-mode' instead.")
+Never set this variable directly, use the command
+`auto-revert-tail-mode' instead.")
(put 'auto-revert-tail-mode 'permanent-local t)
(defvar auto-revert-timer nil
(auto-revert-set-timer))))
(defcustom auto-revert-stop-on-user-input t
- "When non-nil Auto-Revert Mode stops checking files on user input."
+ "When non-nil, user input temporarily interrupts Auto-Revert Mode.
+With this setting, Auto-Revert Mode checks for user input after
+handling each buffer and does not process any further buffers
+\(until the next run of the timer) if user input is available.
+When nil, Auto-Revert Mode checks files and reverts buffers,
+with quitting disabled, without paying attention to user input.
+Thus, with this setting, Emacs might be non-responsive at times."
:group 'auto-revert
:type 'boolean)
(defcustom auto-revert-verbose t
- "When nil, Auto-Revert Mode will not generate any messages.
+ "When nil, Auto-Revert Mode does not generate any messages.
When non-nil, a message is generated whenever a file is reverted."
:group 'auto-revert
:type 'boolean)
\(When the string is not empty, make sure that it has a leading space.)"
:group 'auto-revert
- :type 'string)
+ :type 'string
+ :version "22.1")
(defcustom auto-revert-mode-hook nil
"Functions to run when Auto-Revert Mode is activated."
control info every `auto-revert-interval' seconds. Nevertheless,
it should not cause excessive CPU usage on a reasonably fast
machine, if it does not apply to too many version controlled
-buffers. CPU usage depends on the version control system"
+buffers. CPU usage depends on the version control system."
:group 'auto-revert
:type 'boolean
- :version "21.4")
+ :version "22.1")
(defvar global-auto-revert-ignore-buffer nil
"*When non-nil, Global Auto-Revert Mode will not revert this buffer.
Use `global-auto-revert-mode' to automatically revert all buffers.
Use `auto-revert-tail-mode' if you know that the file will only grow
without being changed in the part that is already in the buffer."
- nil auto-revert-mode-text nil
+ :group 'auto-revert :lighter auto-revert-mode-text
(if auto-revert-mode
(if (not (memq (current-buffer) auto-revert-buffer-list))
(push (current-buffer) auto-revert-buffer-list))
;; else we might reappend our own end when we save
(add-hook 'before-save-hook (lambda () (auto-revert-tail-mode 0)) nil t)
(or (local-variable-p 'auto-revert-tail-pos) ; don't lose prior position
- (set (make-variable-buffer-local 'auto-revert-tail-pos)
+ (set (make-local-variable 'auto-revert-tail-pos)
(save-restriction (widen) (1- (point-max)))))
;; let auto-revert-mode set up the mechanism for us if it isn't already
(or auto-revert-mode
(not (file-remote-p buffer-file-name))
(file-readable-p buffer-file-name)
(not (verify-visited-file-modtime buffer)))
- (and (or auto-revert-mode auto-revert-tail-mode
+ (and (or auto-revert-mode
global-auto-revert-non-file-buffers)
revert-buffer-function
(boundp 'buffer-stale-function)
'no-mini t))
(if auto-revert-tail-mode
(auto-revert-tail-handler)
- (revert-buffer 'ignore-auto 'dont-ask 'preserve-modes))
+ ;; Bind buffer-read-only in case user has done C-x C-q,
+ ;; so as not to forget that. This gives undesirable results
+ ;; when the file's mode changes, but that is less common.
+ (let ((buffer-read-only buffer-read-only))
+ (revert-buffer 'ignore-auto 'dont-ask 'preserve-modes)))
(when buffer-file-name
(when eob (goto-char (point-max)))
(dolist (window eoblist)
(file buffer-file-name)
buffer-file-name) ; ignore that file has changed
(when (> size auto-revert-tail-pos)
+ (undo-boundary)
(save-restriction
(widen)
(save-excursion
(goto-char (point-max))
(insert-file-contents file nil auto-revert-tail-pos size)))
+ (undo-boundary)
(setq auto-revert-tail-pos size)
(set-buffer-modified-p modified)))
(set-visited-file-modtime))
This function is also responsible for removing buffers no longer in
Auto-Revert mode from `auto-revert-buffer-list', and for canceling
the timer when no buffers need to be checked."
- (let ((bufs (if global-auto-revert-mode
- (buffer-list)
- auto-revert-buffer-list))
- (remaining ())
- (new ()))
- ;; Partition `bufs' into two halves depending on whether or not
- ;; the buffers are in `auto-revert-remaining-buffers'. The two
- ;; halves are then re-joined with the "remaining" buffers at the
- ;; head of the list.
- (dolist (buf auto-revert-remaining-buffers)
- (if (memq buf bufs)
- (push buf remaining)))
- (dolist (buf bufs)
- (if (not (memq buf remaining))
- (push buf new)))
- (setq bufs (nreverse (nconc new remaining)))
- (while (and bufs
- (not (and auto-revert-stop-on-user-input
- (input-pending-p))))
- (let ((buf (car bufs)))
- (if (buffer-name buf) ; Buffer still alive?
- (with-current-buffer buf
- ;; Test if someone has turned off Auto-Revert Mode in a
- ;; non-standard way, for example by changing major mode.
- (if (and (not auto-revert-mode)
- (not auto-revert-tail-mode)
- (memq buf auto-revert-buffer-list))
- (setq auto-revert-buffer-list
- (delq buf auto-revert-buffer-list)))
- (when (auto-revert-active-p) (auto-revert-handler)))
- ;; Remove dead buffer from `auto-revert-buffer-list'.
- (setq auto-revert-buffer-list
- (delq buf auto-revert-buffer-list))))
- (setq bufs (cdr bufs)))
- (setq auto-revert-remaining-buffers bufs)
- ;; Check if we should cancel the timer.
- (when (and (not global-auto-revert-mode)
- (null auto-revert-buffer-list))
- (cancel-timer auto-revert-timer)
- (setq auto-revert-timer nil))))
+ (save-match-data
+ (let ((bufs (if global-auto-revert-mode
+ (buffer-list)
+ auto-revert-buffer-list))
+ (remaining ())
+ (new ()))
+ ;; Partition `bufs' into two halves depending on whether or not
+ ;; the buffers are in `auto-revert-remaining-buffers'. The two
+ ;; halves are then re-joined with the "remaining" buffers at the
+ ;; head of the list.
+ (dolist (buf auto-revert-remaining-buffers)
+ (if (memq buf bufs)
+ (push buf remaining)))
+ (dolist (buf bufs)
+ (if (not (memq buf remaining))
+ (push buf new)))
+ (setq bufs (nreverse (nconc new remaining)))
+ (while (and bufs
+ (not (and auto-revert-stop-on-user-input
+ (input-pending-p))))
+ (let ((buf (car bufs)))
+ (if (buffer-name buf) ; Buffer still alive?
+ (with-current-buffer buf
+ ;; Test if someone has turned off Auto-Revert Mode in a
+ ;; non-standard way, for example by changing major mode.
+ (if (and (not auto-revert-mode)
+ (not auto-revert-tail-mode)
+ (memq buf auto-revert-buffer-list))
+ (setq auto-revert-buffer-list
+ (delq buf auto-revert-buffer-list)))
+ (when (auto-revert-active-p) (auto-revert-handler)))
+ ;; Remove dead buffer from `auto-revert-buffer-list'.
+ (setq auto-revert-buffer-list
+ (delq buf auto-revert-buffer-list))))
+ (setq bufs (cdr bufs)))
+ (setq auto-revert-remaining-buffers bufs)
+ ;; Check if we should cancel the timer.
+ (when (and (not global-auto-revert-mode)
+ (null auto-revert-buffer-list))
+ (cancel-timer auto-revert-timer)
+ (setq auto-revert-timer nil)))))
;; The end: