]> code.delx.au - gnu-emacs/blobdiff - lisp/autorevert.el
Merge changes from emacs-24; up to 2012-04-26T02:03:19Z!ueno@unixuser.org
[gnu-emacs] / lisp / autorevert.el
index 3831d7c1c050408ca088f90387c2920a99b0740d..11005f49f448b2f14ddfca4b7c228a4341d91a8e 100644 (file)
@@ -1,7 +1,6 @@
 ;;; autorevert.el --- revert buffers when files on disk change
 
-;; Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004,
-;;   2005, 2006, 2007 Free Software Foundation, Inc.
+;; Copyright (C) 1997-1999, 2001-2012 Free Software Foundation, Inc.
 
 ;; Author: Anders Lindgren <andersl@andersl.com>
 ;; Keywords: convenience
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -21,9 +20,7 @@
 ;; GNU General Public License for more details.
 
 ;; 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., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
@@ -68,6 +65,7 @@
 ;; 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.)
+;; Auto Revert Tail Mode works also for remote files.
 
 ;; Usage:
 ;;
@@ -79,7 +77,7 @@
 ;;   M-x global-auto-revert-mode RET
 ;;
 ;; To activate Global Auto-Revert Mode every time Emacs is started
-;; customise the option `global-auto-revert-mode' or the following
+;; customize the option `global-auto-revert-mode' or the following
 ;; line could be added to your ~/.emacs:
 ;;   (global-auto-revert-mode 1)
 ;;
 
 (defgroup auto-revert nil
   "Revert individual buffers when files on disk change.
-
-Auto-Revert Mode can be activated for individual buffer.
-Global Auto-Revert Mode applies to all buffers."
+Auto-Revert mode enables auto-revert in individual buffers.
+Global Auto-Revert mode does so in all buffers."
   :group 'files
   :group 'convenience)
 
@@ -118,12 +115,12 @@ Global Auto-Revert Mode applies to all buffers."
 ;;; What's this?: ;; Autoload for the benefit of `make-mode-line-mouse-sensitive'.
 ;;; What's this?: ;;;###autoload
 (defvar auto-revert-mode nil
-  "*Non-nil when Auto-Revert Mode is active.
+  "Non-nil when Auto-Revert Mode is active.
 Never set this variable directly, use the command `auto-revert-mode' instead.")
 (put 'auto-revert-mode 'permanent-local t)
 
 (defvar auto-revert-tail-mode nil
-  "*Non-nil when Auto-Revert Tail Mode is active.
+  "Non-nil when Auto-Revert Tail Mode is active.
 Never set this variable directly, use the command
 `auto-revert-tail-mode' instead.")
 (put 'auto-revert-tail-mode 'permanent-local t)
@@ -209,10 +206,13 @@ would only waste precious space."
 When non-nil, both file buffers and buffers with a custom
 `revert-buffer-function' and a `buffer-stale-function' are
 reverted by Global Auto-Revert mode.  These include the Buffer
-List buffer, and Dired buffers showing complete local
-directories.  Dired buffers do not auto-revert as a result of
-changes in subdirectories or in the contents, size, modes, etc.,
-of files.  You may still sometimes want to revert them manually.
+List buffer displayed by `buffer-menu', and Dired buffers showing
+complete local directories.  The Buffer List buffer reverts every
+`auto-revert-interval' seconds; Dired buffers when the file list of
+the main directory changes.  Dired buffers do not auto-revert as
+a result of changes in subdirectories, or in the contents, size,
+modes, etc., of files.  You may still sometimes want to revert
+them manually.
 
 Use this option with care since it could lead to excessive auto-reverts.
 For more information, see Info node `(emacs)Autorevert'."
@@ -253,8 +253,7 @@ buffers.  CPU usage depends on the version control system."
   :version "22.1")
 
 (defvar global-auto-revert-ignore-buffer nil
-  "*When non-nil, Global Auto-Revert Mode will not revert this buffer.
-
+  "When non-nil, Global Auto-Revert Mode will not revert this buffer.
 This variable becomes buffer local when set in any fashion.")
 (make-variable-buffer-local 'global-auto-revert-ignore-buffer)
 
@@ -276,18 +275,23 @@ the list of old buffers.")
   "Position of last known end of file.")
 
 (add-hook 'find-file-hook
-         (lambda ()
-           (set (make-local-variable 'auto-revert-tail-pos)
-                (nth 7 (file-attributes buffer-file-name)))))
+         (lambda ()
+           (set (make-local-variable 'auto-revert-tail-pos)
+                (nth 7 (file-attributes buffer-file-name)))))
 
 ;; Functions:
 
 ;;;###autoload
 (define-minor-mode auto-revert-mode
-  "Toggle reverting buffer when file on disk changes.
+  "Toggle reverting buffer when the file changes (Auto Revert mode).
+With a prefix argument ARG, enable Auto Revert mode if ARG is
+positive, and disable it otherwise.  If called from Lisp, enable
+the mode if ARG is omitted or nil.
+
+Auto Revert mode is a minor mode that affects only the current
+buffer.  When enabled, it reverts the buffer when the file on
+disk changes.
 
-With arg, turn Auto Revert mode on if and only if arg is positive.
-This is a minor mode that affects only the current 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."
@@ -314,14 +318,16 @@ This function is designed to be added to hooks, for example:
 
 ;;;###autoload
 (define-minor-mode auto-revert-tail-mode
-  "Toggle reverting tail of buffer when file on disk grows.
-With arg, turn Tail mode on iff arg is positive.
+  "Toggle reverting tail of buffer when the file grows.
+With a prefix argument ARG, enable Auto-Revert Tail mode if ARG
+is positive, and disable it otherwise.  If called from Lisp,
+enable the mode if ARG is omitted or nil.
 
-When Tail mode is enabled, the tail of the file is constantly
-followed, as with the shell command `tail -f'.  This means that
-whenever the file grows on disk (presumably because some
-background process is appending to it from time to time), this is
-reflected in the current buffer.
+When Auto Revert Tail mode is enabled, the tail of the file is
+constantly followed, as with the shell command `tail -f'.  This
+means that whenever the file grows on disk (presumably because
+some background process is appending to it from time to time),
+this is reflected in the current buffer.
 
 You can edit the buffer and turn this mode off and on again as
 you please.  But make sure the background process has stopped
@@ -334,9 +340,25 @@ Use `auto-revert-mode' for changes other than appends!"
       (auto-revert-tail-mode 0)
       (error "This buffer is not visiting a file"))
     (if (and (buffer-modified-p)
-            (not auto-revert-tail-pos) ; library was loaded only after finding file
+            (zerop auto-revert-tail-pos) ; library was loaded only after finding file
             (not (y-or-n-p "Buffer is modified, so tail offset may be wrong.  Proceed? ")))
        (auto-revert-tail-mode 0)
+      ;; a-r-tail-pos stores the size of the file at the time of the
+      ;; last revert. After this package loads, it adds a
+      ;; find-file-hook to set this variable every time a file is
+      ;; loaded.  If the package is loaded only _after_ visiting the
+      ;; file to be reverted, then we have no idea what the value of
+      ;; a-r-tail-pos should have been when the file was visited.  If
+      ;; the file has changed on disk in the meantime, all we can do
+      ;; is offer to revert the whole thing. If you choose not to
+      ;; revert, then you might miss some output then happened
+      ;; between visiting the file and activating a-r-t-mode.
+      (and (zerop auto-revert-tail-pos)
+           (not (verify-visited-file-modtime (current-buffer)))
+           (y-or-n-p "File changed on disk, content may be missing.  \
+Perform a full revert? ")
+           ;; Use this (not just revert-buffer) for point-preservation.
+           (auto-revert-handler))
       ;; 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
@@ -351,7 +373,7 @@ Use `auto-revert-mode' for changes other than appends!"
 
 ;;;###autoload
 (defun turn-on-auto-revert-tail-mode ()
-  "Turn on Auto-Revert Tail Mode.
+  "Turn on Auto-Revert Tail mode.
 
 This function is designed to be added to hooks, for example:
   (add-hook 'my-logfile-mode-hook 'turn-on-auto-revert-tail-mode)"
@@ -360,11 +382,24 @@ This function is designed to be added to hooks, for example:
 
 ;;;###autoload
 (define-minor-mode global-auto-revert-mode
-  "Revert any buffer when file on disk changes.
-
-With arg, turn Auto Revert mode on globally if and only if arg is positive.
-This is a minor mode that affects all buffers.
-Use `auto-revert-mode' to revert a particular buffer."
+  "Toggle Global Auto Revert mode.
+With a prefix argument ARG, enable Global Auto Revert mode if ARG
+is positive, and disable it otherwise.  If called from Lisp,
+enable the mode if ARG is omitted or nil.
+
+Global Auto Revert mode is a global minor mode that reverts any
+buffer associated with a file when the file changes on disk.  Use
+`auto-revert-mode' to revert a particular buffer.
+
+If `global-auto-revert-non-file-buffers' is non-nil, this mode
+may also revert some non-file buffers, as described in the
+documentation of that variable.  It ignores buffers with modes
+matching `global-auto-revert-ignore-modes', and buffers with a
+non-nil vale of `global-auto-revert-ignore-buffer'.
+
+This function calls the hook `global-auto-revert-mode-hook'.
+It displays the text that `global-auto-revert-mode-text'
+specifies in the mode line."
   :global t :group 'auto-revert :lighter global-auto-revert-mode-text
   (auto-revert-set-timer)
   (when global-auto-revert-mode
@@ -400,12 +435,22 @@ will use an up-to-date value of `auto-revert-interval'"
   "Revert current buffer, if appropriate.
 This is an internal function used by Auto-Revert Mode."
   (when (or auto-revert-tail-mode (not (buffer-modified-p)))
-    (let* ((buffer (current-buffer))
+    (let* ((buffer (current-buffer)) size
           (revert
            (or (and buffer-file-name
-                    (not (file-remote-p buffer-file-name))
-                    (file-readable-p buffer-file-name)
-                    (not (verify-visited-file-modtime buffer)))
+                    (if auto-revert-tail-mode
+                        ;; Tramp caches the file attributes.  Setting
+                        ;; `remote-file-name-inhibit-cache' forces Tramp
+                        ;; to reread the values.
+                        (let ((remote-file-name-inhibit-cache t))
+                          (and (file-readable-p buffer-file-name)
+                               (/= auto-revert-tail-pos
+                                   (setq size
+                                         (nth 7 (file-attributes
+                                                 buffer-file-name))))))
+                      (and (not (file-remote-p buffer-file-name))
+                           (file-readable-p buffer-file-name)
+                           (not (verify-visited-file-modtime buffer)))))
                (and (or auto-revert-mode
                         global-auto-revert-non-file-buffers)
                     revert-buffer-function
@@ -423,13 +468,13 @@ This is an internal function used by Auto-Revert Mode."
        (when buffer-file-name
          (setq eob (eobp))
          (walk-windows
-          #'(lambda (window)
-              (and (eq (window-buffer window) buffer)
-                   (= (window-point window) (point-max))
-                   (push window eoblist)))
+          (lambda (window)
+            (and (eq (window-buffer window) buffer)
+                 (= (window-point window) (point-max))
+                 (push window eoblist)))
           'no-mini t))
        (if auto-revert-tail-mode
-           (auto-revert-tail-handler)
+           (auto-revert-tail-handler size)
          ;; 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.
@@ -444,20 +489,22 @@ This is an internal function used by Auto-Revert Mode."
       (when (or revert auto-revert-check-vc-info)
        (vc-find-file-hook)))))
 
-(defun auto-revert-tail-handler ()
-  (let ((size (nth 7 (file-attributes buffer-file-name)))
-       (modified (buffer-modified-p))
+(defun auto-revert-tail-handler (size)
+  (let ((modified (buffer-modified-p))
        (inhibit-read-only t)           ; Ignore.
        (file buffer-file-name)
        (buffer-file-name nil))         ; Ignore that file has changed.
-    (when (> size auto-revert-tail-pos)
+    (when (/= auto-revert-tail-pos size)
       (run-hooks 'before-revert-hook)
       (undo-boundary)
       (save-restriction
        (widen)
        (save-excursion
          (goto-char (point-max))
-         (insert-file-contents file nil auto-revert-tail-pos size)))
+         (insert-file-contents file nil
+                               (and (< auto-revert-tail-pos size)
+                                    auto-revert-tail-pos)
+                               size)))
       (run-hooks 'after-revert-hook)
       (undo-boundary)
       (setq auto-revert-tail-pos size)
@@ -508,7 +555,7 @@ the timer when no buffers need to be checked."
                  (not (and auto-revert-stop-on-user-input
                            (input-pending-p))))
        (let ((buf (car bufs)))
-         (if (buffer-name buf)         ; Buffer still alive?
+          (if (buffer-live-p buf)
              (with-current-buffer buf
                ;; Test if someone has turned off Auto-Revert Mode in a
                ;; non-standard way, for example by changing major mode.
@@ -535,5 +582,4 @@ the timer when no buffers need to be checked."
 
 (run-hooks 'auto-revert-load-hook)
 
-;; arch-tag: f6bcb07b-4841-477e-9e44-b18678e58876
 ;;; autorevert.el ends here