(display_text_line): Handle the case of point being in
[emacs.git] / lisp / autorevert.el
blob7670730b21c6f909951951e0dcd231e4961c2c49
1 ;; autorevert --- Revert buffers when file on disk change.
3 ;; Copyright (C) 1997 Free Software Foundation, Inc.
5 ;; Author: Anders Lindgren <andersl@csd.uu.se>
6 ;; Created: 1 Jun 1997
7 ;; Date: 3 Jul 1997
9 ;; This file is part of GNU Emacs.
11 ;; GNU Emacs is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; any later version.
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
26 ;;; Commentary:
28 ;; Introduction:
30 ;; Whenever a file that Emacs is editing has been changed by another
31 ;; program the user normally have to execute the command `revert-buffer'
32 ;; to load the new content of the file into Emacs.
34 ;; This package contains two minor modes: Global Auto-Revert Mode and
35 ;; Auto-Revert Mode. Both modes automatically reverts buffers
36 ;; whenever the corresponding files have been changed on disk.
38 ;; Auto-Revert Mode can be activated for individual buffers.
39 ;; Global Auto-Revert Mode applies to all file buffers.
41 ;; Both modes operates by checking the time stamp of all files at
42 ;; given intervals, the default is every five seconds. The check is
43 ;; aborted whenever the user actually use Emacs. Hopefully you will
44 ;; never even notice that this package is active (except that your
45 ;; buffers will be reverted, of course).
47 ;; Installation:
49 ;; To install this package, place it in somewhere on Emacs' load-path,
50 ;; byte-compile it (not necessary), and place the following lines in
51 ;; the appropriate init file:
53 ;; (autoload 'auto-revert-mode "autorevert" nil t)
54 ;; (autoload 'turn-on-auto-revert-mode "autorevert" nil nil)
55 ;; (autoload 'global-auto-revert-mode "autorevert" nil t)
57 ;; Usage:
59 ;; Go to the appropriate buffer and press:
60 ;; M-x auto-revert-mode RET
62 ;; To activate Global Auto-Revert Mode, press:
63 ;; M-x global-auto-revert-mode RET
65 ;; To activate Global Auto-Revert Mode every time Emacs is started the
66 ;; following line could be added to your ~/.emacs:
67 ;; (global-auto-revert-mode 1)
69 ;; The function `turn-on-auto-revert-mode' could be added to any major
70 ;; mode hook to activate Auto-Revert Mode for all buffers in that
71 ;; mode. For example, the following line will activate Auto-Revert
72 ;; Mode in all C mode buffers:
74 ;; (add-hook 'c-mode-hook 'turn-on-auto-revert-mode)
76 ;;; Code:
78 ;; Dependencies:
80 (require 'timer)
81 (eval-when-compile (require 'cl))
84 ;; Custom Group:
86 ;; The two modes will be placed next to Auto Save Mode under the
87 ;; Files group under Emacs.
89 (defgroup auto-revert nil
90 "Revert individual buffer when file on disk change.
92 Auto-Revert Mode can be activated for individual buffer.
93 Global Auto-Revert Mode applies to all buffers."
94 :group 'files)
97 ;; Variables:
99 (defvar auto-revert-mode nil
100 "*Non-nil when Auto-Revert Mode is active.
102 Do never set this variable directly, use the command
103 `auto-revert-mode' instead.")
105 (defcustom global-auto-revert-mode nil
106 "When on, buffers are automatically reverted when files on disk change.
108 Set this variable when using \\[customize] only. Otherwise, use the
109 command `global-auto-revert-mode' instead."
110 :group 'auto-revert
111 :initialize 'custom-initialize-default
112 :set '(lambda (symbol value)
113 (global-auto-revert-mode (or value 0)))
114 :type 'boolean
115 :require 'autorevert)
117 (defcustom auto-revert-interval 5
118 "Time, in seconds, between Auto-Revert Mode file checks."
119 :group 'auto-revert
120 :type 'integer)
122 (defcustom auto-revert-stop-on-user-input t
123 "When non-nil Auto-Revert Mode stops checking files on user input."
124 :group 'auto-revert
125 :type 'boolean)
127 (defcustom auto-revert-verbose t
128 "When nil, Auto-Revert Mode will not generate any messages.
130 Currently, messages are generated when the mode is activated or
131 deactivated, and whenever a file is reverted."
132 :group 'auto-revert
133 :type 'boolean)
135 (defcustom auto-revert-mode-text " ARev"
136 "String to display in the mode line when Auto-Revert Mode is active.
138 \(When the string is not empty, make sure that it has a leading space.)"
139 :tag "Auto Revert Mode Text" ; To separate it from `global-...'
140 :group 'auto-revert
141 :type 'string)
143 (defcustom auto-revert-mode-hook nil
144 "Functions to run when Auto-Revert Mode is activated."
145 :tag "Auto Revert Mode Hook" ; To separate it from `global-...'
146 :group 'auto-revert
147 :type 'hook)
149 (defcustom global-auto-revert-mode-text ""
150 "String to display when Global Auto-Revert Mode is active.
152 The default is nothing since when this mode is active this text doesn't
153 vary neither over time, nor between buffers. Hence a mode line text
154 would only waste precious space."
155 :group 'auto-revert
156 :type 'string)
158 (defcustom global-auto-revert-mode-hook nil
159 "Hook called when Global Auto-Revert Mode is activated."
160 :group 'auto-revert
161 :type 'hook)
163 (defcustom global-auto-revert-non-file-buffers nil
164 "*When nil only file buffers are reverted by Global Auto-Revert Mode.
166 When non-nil, both file buffers and buffers with a custom
167 `revert-buffer-function' are reverted by Global Auto-Revert Mode."
168 :group 'auto-revert
169 :type 'boolean)
171 (defcustom global-auto-revert-non-file-buffers nil
172 "When nil only file buffers are reverted by Global Auto-Revert Mode.
174 When non-nil, both file buffers and buffers with a custom
175 `revert-buffer-function' are reverted by Global Auto-Revert Mode.
177 Use this option with care since it could lead to excessive reverts."
178 :group 'auto-revert
179 :type 'boolean)
181 (defcustom global-auto-revert-ignore-modes '()
182 "List of major modes Global Auto-Revert Mode should not check."
183 :group 'auto-revert
184 :type '(repeat sexp))
186 (defcustom auto-revert-load-hook nil
187 "Functions to run when Auto-Revert Mode is first loaded."
188 :tag "Load Hook"
189 :group 'auto-revert
190 :type 'hook)
192 (defvar global-auto-revert-ignore-buffer nil
193 "*When non-nil, Gobal Auto-Revert Mode will not revert this buffer.
195 This variable becomes buffer local when set in any faishon.")
196 (make-variable-buffer-local 'global-auto-revert-ignore-buffer)
199 ;; Internal variables:
201 (defvar auto-revert-buffer-list '()
202 "List of buffers in Auto-Revert Mode.
204 Note that only Auto-Revert Mode, never Global Auto-Revert Mode, adds
205 buffers to this list.
207 The timer function `auto-revert-buffers' is responsible for purging
208 the list of old buffers.")
210 (defvar auto-revert-timer nil
211 "Timer used by Auto-Revert Mode.")
213 (defvar auto-revert-remaining-buffers '()
214 "Buffers not checked when user input stopped execution.")
217 ;; Functions:
219 ;;;###autoload
220 (defun auto-revert-mode (&optional arg)
221 "Revert buffer when file on disk change.
223 This is a minor mode that affect only the current buffer.
224 Use `global-auto-revert-mode' to automatically revert all buffers."
225 (interactive "P")
226 (make-local-variable 'auto-revert-mode)
227 (setq auto-revert-mode
228 (if (null arg)
229 (not auto-revert-mode)
230 (> (prefix-numeric-value arg) 0)))
231 (if (and auto-revert-verbose
232 (interactive-p))
233 (message "Auto-Revert Mode is now %s."
234 (if auto-revert-mode "on" "off")))
235 (if auto-revert-mode
236 (if (not (memq (current-buffer) auto-revert-buffer-list))
237 (push (current-buffer) auto-revert-buffer-list))
238 (setq auto-revert-buffer-list
239 (delq (current-buffer) auto-revert-buffer-list)))
240 (auto-revert-set-timer)
241 (when auto-revert-mode
242 (auto-revert-buffers)
243 (run-hooks 'auto-revert-mode-hook)))
246 ;;;###autoload
247 (defun turn-on-auto-revert-mode ()
248 "Turn on Auto-Revert Mode.
250 This function is designed to be added to hooks, for example:
251 (add-hook 'c-mode-hook 'turn-on-auto-revert-mode)"
252 (auto-revert-mode 1))
255 ;;;###autoload
256 (defun global-auto-revert-mode (&optional arg)
257 "Revert any buffer when file on disk change.
259 This is a minor mode that affect all buffers.
260 Use `auto-revert-mode' to revert a particular buffer."
261 (interactive "P")
262 (setq global-auto-revert-mode
263 (if (null arg)
264 (not global-auto-revert-mode)
265 (> (prefix-numeric-value arg) 0)))
266 (if (and auto-revert-verbose
267 (interactive-p))
268 (message "Gobal Auto-Revert Mode is now %s."
269 (if global-auto-revert-mode "on" "off")))
270 (auto-revert-set-timer)
271 (when global-auto-revert-mode
272 (auto-revert-buffers)
273 (run-hooks 'global-auto-revert-mode-hook)))
276 (defun auto-revert-set-timer ()
277 "Restart or cancel the timer."
278 (if (timerp auto-revert-timer)
279 (cancel-timer auto-revert-timer))
280 (if (or global-auto-revert-mode auto-revert-buffer-list)
281 (setq auto-revert-timer (run-with-timer auto-revert-interval
282 auto-revert-interval
283 'auto-revert-buffers))
284 (setq auto-revert-timer nil)))
287 (defun auto-revert-buffers ()
288 "Revert buffers as specified by Auto-Revert and Global Auto-Revert Mode.
290 Should `global-auto-revert-mode' be active all file buffers are checked.
292 Should `auto-revert-mode' be active in some buffers, those buffers
293 are checked.
295 Non-file buffers that have a custom `revert-buffer-function' are
296 reverted either when Auto-Revert Mode is active in that buffer, or
297 when the variable `global-auto-revert-non-file-buffers' is non-nil
298 and Global Auto-Revert Mode is active.
300 This function stops whenever the user use Emacs. The buffers not
301 checked are stored in the variable `auto-revert-remaining-buffers'.
303 To avoid starvation, the buffers in `auto-revert-remaining-buffers'
304 are checked first the next time this function is called.
306 This function is also responslible for removing buffers no longer in
307 Auto-Revert mode from `auto-revert-buffer-list', and for canceling
308 the timer when no buffers need to be checked."
309 (let ((bufs (if global-auto-revert-mode
310 (buffer-list)
311 auto-revert-buffer-list))
312 (remaining '())
313 (new '()))
314 ;; Partition `bufs' into two halves depending on whether or not
315 ;; the buffers are in `auto-revert-remaining-buffers'. The two
316 ;; halves are then re-joined with the "remaining" buffers at the
317 ;; head of the list.
318 (dolist (buf auto-revert-remaining-buffers)
319 (if (memq buf bufs)
320 (push buf remaining)))
321 (dolist (buf bufs)
322 (if (not (memq buf remaining))
323 (push buf new)))
324 (setq bufs (nreverse (nconc new remaining)))
325 (while (and bufs
326 (not (and auto-revert-stop-on-user-input
327 (input-pending-p))))
328 (let ((buf (car bufs)))
329 (if (buffer-name buf) ; Buffer still alive?
330 (save-excursion
331 (set-buffer buf)
332 ;; Test if someone has turned off Auto-Revert Mode in a
333 ;; non-standard way, for example by changing major mode.
334 (if (and (not auto-revert-mode)
335 (memq buf auto-revert-buffer-list))
336 (setq auto-revert-buffer-list
337 (delq buf auto-revert-buffer-list)))
338 (when (and
339 (or auto-revert-mode
340 (and
341 global-auto-revert-mode
342 (not global-auto-revert-ignore-buffer)
343 (not (memq major-mode
344 global-auto-revert-ignore-modes))))
345 (not (buffer-modified-p))
346 (if (buffer-file-name)
347 (and (file-readable-p (buffer-file-name))
348 (not (verify-visited-file-modtime buf)))
349 (and revert-buffer-function
350 (or (and global-auto-revert-mode
351 global-auto-revert-non-file-buffers)
352 auto-revert-mode))))
353 (if auto-revert-verbose
354 (message "Reverting buffer `%s'." buf))
355 (revert-buffer t t)))
356 ;; Remove dead buffer from `auto-revert-buffer-list'.
357 (setq auto-revert-buffer-list
358 (delq buf auto-revert-buffer-list))))
359 (setq bufs (cdr bufs)))
360 (setq auto-revert-remaining-buffers bufs)
361 ;; Check if we should cancel the timer.
362 (when (and (not global-auto-revert-mode)
363 (null auto-revert-buffer-list))
364 (cancel-timer auto-revert-timer)
365 (setq auto-revert-timer nil))))
368 ;; The end:
370 (unless (assq 'auto-revert-mode minor-mode-alist)
371 (push '(auto-revert-mode auto-revert-mode-text)
372 minor-mode-alist))
373 (unless (assq 'global-auto-revert-mode minor-mode-alist)
374 (push '(global-auto-revert-mode global-auto-revert-mode-text)
375 minor-mode-alist))
377 (provide 'autorevert)
379 (run-hooks 'auto-revert-load-hook)
381 ;; This makes it possible to set Global Auto-Revert Mode from
382 ;; Customize.
383 (if global-auto-revert-mode
384 (global-auto-revert-mode 1))
386 ;; autorevert.el ends here.