209
+ − 1 ;;; itimer-autosave.el --- Autosave functions with itimers
+ − 2
+ − 3 ;; Copyright status unknown
+ − 4
+ − 5 ;; Maintainer: XEmacs Development Team
+ − 6 ;; Keywords: internal, dumped
+ − 7
+ − 8 ;; This file is part of XEmacs.
+ − 9
+ − 10 ;; XEmacs is free software; you can redistribute it and/or modify it
+ − 11 ;; under the terms of the GNU General Public License as published by
+ − 12 ;; the Free Software Foundation; either version 2, or (at your option)
+ − 13 ;; any later version.
+ − 14
+ − 15 ;; XEmacs is distributed in the hope that it will be useful, but
+ − 16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
+ − 17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ − 18 ;; General Public License for more details.
+ − 19
+ − 20 ;; You should have received a copy of the GNU General Public License
+ − 21 ;; along with XEmacs; see the file COPYING. If not, write to the Free
+ − 22 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ − 23 ;; 02111-1307, USA.
+ − 24
+ − 25 ;;; Synched up with: Not in FSF.
+ − 26
+ − 27 ;;; Commentary:
+ − 28
+ − 29 ;; This file is dumped with XEmacs.
+ − 30
+ − 31 ;; itimer-driven auto-saves
+ − 32
+ − 33 ;;; Code:
+ − 34
+ − 35 ;jwz: this is preloaded so don't ;;;###autoload
+ − 36 (defvar auto-save-timeout 960
+ − 37 "*Number of seconds idle time before auto-save.
+ − 38 Zero or nil means disable auto-saving due to idleness.
+ − 39
+ − 40 The actual amount of idle time between auto-saves is logarithmically related
+ − 41 to the size of the current buffer. This variable is the number of seconds
+ − 42 after which an auto-save will happen when the current buffer is 50k or less;
+ − 43 the timeout will be 2 1/4 times this in a 200k buffer, 3 3/4 times this in a
+ − 44 1000k buffer, and 4 1/2 times this in a 2000k buffer.
+ − 45
+ − 46 See also the variable `auto-save-interval', which controls auto-saving based
+ − 47 on the number of characters typed.")
+ − 48
+ − 49 ;jwz: this is preloaded so don't ;;;###autoload
+ − 50 (defvar auto-gc-threshold (/ gc-cons-threshold 3)
+ − 51 "*GC when this many bytes have been consed since the last GC,
+ − 52 and the user has been idle for `auto-save-timeout' seconds.")
+ − 53
+ − 54 (defun auto-save-itimer ()
+ − 55 "For use as a itimer callback function.
+ − 56 Auto-saves and garbage-collects based on the size of the current buffer
+ − 57 and the value of `auto-save-timeout', `auto-gc-threshold', and the current
+ − 58 keyboard idle-time."
+ − 59 (if (or (null auto-save-timeout)
+ − 60 (<= auto-save-timeout 0)
+ − 61 (eq (minibuffer-window) (selected-window)))
+ − 62 nil
+ − 63 (let ((buf-size (1+ (ash (buffer-size) -8)))
+ − 64 (delay-level 0)
+ − 65 (now (current-time))
+ − 66 delay)
+ − 67 (while (> buf-size 64)
+ − 68 (setq delay-level (1+ delay-level)
+ − 69 buf-size (- buf-size (ash buf-size -2))))
+ − 70 (if (< delay-level 4)
+ − 71 (setq delay-level 4))
+ − 72 ;; delay_level is 4 for files under around 50k, 7 at 100k, 9 at 200k,
+ − 73 ;; 11 at 300k, and 12 at 500k, 15 at 1 meg, and 17 at 2 meg.
+ − 74 (setq delay (/ (* delay-level auto-save-timeout) 4))
+ − 75 (let ((idle-time (if (or (not (consp last-input-time))
+ − 76 (/= (car now) (car last-input-time)))
+ − 77 (1+ delay)
+ − 78 (- (car (cdr now)) (cdr last-input-time)))))
+ − 79 (and (> idle-time delay)
+ − 80 (do-auto-save))
+ − 81 (and (> idle-time auto-save-timeout)
+ − 82 (> (consing-since-gc) auto-gc-threshold)
+ − 83 (garbage-collect)))))
+ − 84 ;; Look at the itimer that's currently running; if the user has changed
+ − 85 ;; the value of auto-save-timeout, modify this itimer to have the correct
+ − 86 ;; restart time. There will be some latency between when the user changes
+ − 87 ;; this variable and when it takes effect, but it will happen eventually.
+ − 88 (let ((self (get-itimer "auto-save")))
+ − 89 (or self (error "auto-save-itimer can't find itself"))
+ − 90 (if (and auto-save-timeout (> auto-save-timeout 4))
+ − 91 (or (= (itimer-restart self) (/ auto-save-timeout 4))
+ − 92 (set-itimer-restart self (/ auto-save-timeout 4)))))
+ − 93 nil)
+ − 94
+ − 95 (defun itimer-init-auto-gc ()
+ − 96 (or noninteractive ; may be being run from after-init-hook in -batch mode.
+ − 97 (get-itimer "auto-save")
+ − 98 ;; the time here is just the first interval; if the user changes it
+ − 99 ;; later, it will adjust.
+ − 100 (let ((time (max 2 (/ (or auto-save-timeout 30) 4))))
+ − 101 (start-itimer "auto-save" 'auto-save-itimer time time))))
+ − 102
+ − 103 (cond (purify-flag
+ − 104 ;; This file is being preloaded into an emacs about to be dumped.
+ − 105 ;; So arrange for the auto-save itimer to be started once emacs
+ − 106 ;; is launched.
+ − 107 (add-hook 'after-init-hook 'itimer-init-auto-gc))
+ − 108 (t
+ − 109 ;; Otherwise, this file is being loaded into a normal, interactive
+ − 110 ;; emacs. Start the auto-save timer now.
+ − 111 (itimer-init-auto-gc)))
+ − 112
+ − 113
+ − 114 ;;; itimer-autosave.el ends here