[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Auto Save Mode for ZMACS
Alright, here it goes. No strings attached. It's about three pages
of code. Have fun.
..................
... andreas ..:-).
..................
**** cut here ****
;;; -*- Mode: LISP; Syntax: Common-lisp; Package: ZWEI; Base: 10 -*-
(defvar D,#TD1PsT[Begin using 006 escapes](1 0 (NIL 0) (NIL :BOLD NIL) "CPTFONTCB")*checkpoint-interval* (2 0 (NIL 0) (NIL NIL NIL) "CPTFONT")(* 3 60) ;This must be a global variable - not
"Seconds between auto-saving.") ;a per buffer zwei variable.
(defcom 1com-set-checkpoint-interval2 "Set the time in seconds between checkpoints." ()
(setq *checkpoint-interval* (typein-line-accept '(cl:integer 0 *)
:prompt "Time in seconds between checkpoints"
:default *checkpoint-interval*))
dis-none)
(set-comtab *zmacs-comtab* () (make-command-alist '(com-set-checkpoint-interval)))
(defvariable 1*checkpoint-p* 2t :boolean "Checkpoint this buffer.
If true, the buffer will be saved every *checkpoint-interval* seconds to a checkpoint file.
See M-x Set Checkpoint Interval.")
(loop for v in '(1*checkpoint-p*2) do ;(3 0 (NIL 0) (:SWISS :ROMAN :SMALLER) "HL10")What a kludge!!!!
2 (set v (get v 'variable-init)))
;;;;(4 0 (NIL 0) (:SWISS :ROMAN :LARGER) "HL14") (5 0 (NIL 0) (:SWISS NIL :LARGE) "HL14")Checkpoint4 Pathname
2;;;3 By defining methods for this message you can control where auto save files
2;;;3 are created. You can, e.g., modify the following methods to auto save on
2;;;3 a different host.
2(defmethod (1:checkpoint-pathname 2fs:unix42-pathname-mixin) ()
(send self :new-pathname
:raw-name (string-append "#" fs:name)
:raw-type (string-append fs:type "#")))
(defmethod (1:checkpoint-pathname 2fs:lmfs-pathname-mixin) ()
(send self :new-pathname
:raw-name (string-append "#" fs:name "#")
:version 1))
(defun 1checkpoint-demon 2()
(loop for *interval* in *zmacs-buffer-list*
for *major-mode* = (send *interval* :get :major-mode)
when (and *checkpoint-p* ;3This is a tricky ZWEI symbol macro. Needs global
2 ;3variables *interval* and *major-mode*.
2 (typep *interval* 'file-buffer-mixin) ;3Must have an associated file.
2 (send *interval* :modified-p :explicit-saving) ;3Only save modified buffers
2 (let ((checkpoint-tick (send *interval* :get :checkpoint-tick))) ;3that have been modified
2 (or (null checkpoint-tick) ;3since last autosaved.
2 ( checkpoint-tick (send *interval* :tick)))))
do (checkpoint-interval *interval*))
(si:add-timer-queue-entry (list :relative *checkpoint-interval*)
:once
"ZMACS Checkpoint Demon"
#'checkpoint-demon))
(defvar 1*alternate-checkpoint-pathnames* 2nil)
(defcom 1com-set-checkpoint-file2 "Set the name of the checkpoint file." ()
(let* ((pathname (send *interval* :pathname))
(checkpoint-pathname (typein-line-accept '((scl:token-or-type (("Default" . :default)) fs:pathname))
:prompt "Checkpoint pathname or 'Default'"
:default (cl:getf *alternate-checkpoint-pathnames* pathname :default))))
(if (eq checkpoint-pathname :default)
(cl:remf *alternate-checkpoint-pathnames* pathname)
(setf (cl:getf *alternate-checkpoint-pathnames* pathname) checkpoint-pathname)))
dis-none)
(set-comtab *zmacs-comtab* () (make-command-alist '(com-set-checkpoint-file)))
(defun 1checkpoint-interval 2(interval)
(loop with pathname = (send interval :pathname)
with checkpoint-pathname = (or (cl:getf *alternate-checkpoint-pathnames* pathname)
(condition-case ()
(send pathname :checkpoint-pathname)
;;(6 0 (NIL 0) (:DUTCH NIL :SMALLER) "TR10")Pathnames not to be checkpointed.
2 (sys:unclaimed-message
(return-from checkpoint-interval nil))))
do
;;6 We offer multiple restart handlers offering different choices to the user. The conditions
2 ;;6 are the same for each.
2 (catch-error-restart ((sys:host-not-responding
fs:tcp-ftp-file-name-not-allowed
fs:file-not-found) ;6This error is signalled if we have been denied permission
2 ;6to create the checkpoint file. This can happen when we edit another person's file.
2 "Use a different checkpoint file from now on. (see: M-x Set Checkpoint File)")
(catch-error-restart ((sys:host-not-responding fs:tcp-ftp-file-name-not-allowed fs:file-not-found)
"Mark buffer checkpointed; do not write a checkpoint file until next modification.")
(catch-error-restart ((sys:host-not-responding fs:tcp-ftp-file-name-not-allowed fs:file-not-found)
"Turn off checkpointing for this file. (see: M-x Set Variable Checkpoint-P)")
(catch-error-restart ((sys:host-not-responding fs:tcp-ftp-file-name-not-allowed fs:file-not-found)
"Try again after one checkpoint interval (~\\Time-interval\\)." *checkpoint-interval*)
(return-from checkpoint-interval
(with-open-file (stream checkpoint-pathname
:direction :output
:if-exists :supersede
:element-type (if (interval-fat-p interval) 'cl:character
'cl:string-char))
(stream-out-interval stream interval)
(close stream)
(send interval :putprop (send interval :tick) :checkpoint-tick)
#+XXX(typein-line "~\\datime\\ Written: ~A" (send stream :truename)))))
(return-from checkpoint-interval nil))
(send interval :set-variable-value '*checkpoint-p* nil)
(return-from checkpoint-interval nil))
(send interval :putprop (send interval :tick) :checkpoint-tick)
(return-from checkpoint-interval nil))
(setq checkpoint-pathname
(scl:accept 'fs:pathname :prompt (format nil "New checkpoint pathname for ~A" pathname)
:default (let ((new-name (send (si:pathname-history-first-pathname) ;6Really we want our own history.
2 :new-name (send pathname :name))))
(condition-case ()
(send new-name :checkpoint-pathname)
(sys:unclaimed-message
new-name)))))
(setf (cl:getf *alternate-checkpoint-pathnames* pathname) checkpoint-pathname)))
(add-initialization "ZMACS Checkpoint Demon"
(si:add-timer-queue-entry (list :relative *checkpoint-interval*)
:once
"ZMACS Checkpoint Demon"
#'checkpoint-demon)
'(:once))
;;;;(7 0 (NIL 0) (:DUTCH NIL :LARGER) "DUTCH14") Logout
2;;;6 At logout time we need to prevent the system from trying to checkpoint buffers
2;;;6 that have been left around. Also when another user logs in, he/she should not be
2;;;6 bothered with checkpointing of buffers that do not belong to him/her - they would
2;;;6 be written with the new user as the author etc..
2;;;6 Therefore we mark all modified buffers checkpointed. Now, when the next user
2;;;6 who logs in modifies one of these buffers, then the demon will restart attempting
2;;;6 to checkpoint the file. If the user does not have permission to create the
2;;;6 checkpoint file, we offer the following proceed options:
2;;;6 (1) marking the buffer checkpointed without actually checkpointing it,
2;;;6 (2) turning off checkpointing, and
2;;;6 (3) checkpointing it to a different file.
2(add-initialization "Mark buffers checkpointed" '(mark-buffers-checkpointed) nil 'si:logout-initialization-list)
(defun 1mark-buffers-checkpointed2 ()
(loop for *interval* in *zmacs-buffer-list*
for *major-mode* = (send *interval* :get :major-mode)
when (and *checkpoint-p* ;3This is a tricky ZWEI symbol macro. Needs global
2 ;3variables *interval* and *major-mode*.
2 (typep *interval* 'file-buffer-mixin) ;3Must have an associated file.
2 (send *interval* :modified-p :explicit-saving)) ;3Only save modified buffers
2 do (send *interval* :putprop (send *interval* :tick)
:checkpoint-tick)))
**** cut here ****