home *** CD-ROM | disk | FTP | other *** search
- ;; achieve.el -- functions to achieve a captured state of an emacs session
- ;; This is file 2 of two files in the "regression" part of the "test" package.
- ;; See also capture.el
- ;; Carl Lagoze, Franklin Davis
- ;; Copyright 1987 Wang Institute of Graduate Studies
- ;; $Header: tst-achieve.el,v 1.8 87/07/29 22:50:12 bliven Exp $
-
- (provide 'tst-achieve)
-
- (defun member (elt list)
- "Returns non-nil if ELT is an element of LIST. Comparison done with equal.
- The value is actually the tail of LIST whose car is ELT."
- (while (and list (not (equal elt (car list))))
- (setq list (cdr list)))
- list)
-
- (defmacro cadr (l)
- (list 'car (list 'cdr l)))
-
- (defmacro cddr (l)
- (list 'cdr (list 'cdr l)))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; interactive functions
-
- (defun tst-read-state-from-file (statevar file)
- "Read a captured emacs session state into STATE VARIABLE from FILE."
- (interactive "xState variable to read into: \nfFile Name: ")
- (let ()
- (save-excursion
- (message "Reading file...")
- (switch-to-buffer (make-temp-name "state"))
- (insert-file file)
- (goto-char (point-min))
- (message "Getting state from file...")
- (set statevar (read (current-buffer)))
- (kill-buffer (current-buffer))
- statevar
- ) ; save-excursion
- ) ; let
- ) ; defun tst-read-state-from-file
-
- (defun tst-achieve-state-from-file (file &optional no-process)
- "Achieve a captured emacs session state from a FILE."
- (interactive "fFile Name: ")
- (let (state)
- (tst-read-state-from-file 'state file)
- (tst-achieve-state state no-process)
- ) ; let
- ) ; defun tst-achieve-state-from-file
-
-
- (defun tst-achieve-state (state &optional no-process)
- "Achieve the saved state of an emacs session from variable STATE.
- If tst-achieve-buffers-nondestructively is non nil, buffers not in
- STATE are not killed. If NO_PROCESS is non nil, processes are not achieved."
- (interactive "XState to achieve: ")
- (let ()
- (tst-achieve-bufs-state (cadr (assoc 'buffers state)))
- (message "Achieving state of windows...")
- (delete-other-windows)
- (tst-achieve-windows-state (cadr (assoc 'windows state)))
- (or no-process
- (tst-achieve-processes-state (cadr (assoc 'processes state))))
- (tst-achieve-globals-state (cadr (assoc 'session state)))
- (if (interactive-p)
- (message (concat "Achieved state from " state ".")))
- ) ;let
- ) ;defun tst-achieve-state
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; globals
-
- (defun tst-achieve-globals-state (ses-state)
- "Achieve global attributes saved in STATE"
- (message "Achieving state of globals...")
- (tst-achieve-syms (cadr (assoc 'global-bound-syms ses-state)) nil)
- ;; (tst-achieve-ses-functions-state)
- ;; (tst-achieve-recursive-level-state) ; only the level is captured, not
- ; the actual stack, so useless
- (ding) (ding)
- ) ;defun tst-achieve-globals-state
-
- (defun tst-achieve-syms (pairs localflag)
- "Set the value of symbols to those values in the list of PAIRS. Make
- variable local first if LOCALFLAG non nil.
- Each element of PAIRS looks like (symbol-name . symbol-value)"
- (mapcar
- ; the lambda here allows
- ; mapcar to pass a second
- ; argument localflag to
- ; function tst-achieve-sym,
- ; while applying it to every
- ; element in list pairs
- '(lambda (pair)
- (tst-achieve-sym pair localflag))
- pairs)
- ) ;defun tst-achieve-syms
-
- (defun tst-achieve-sym (pair localflag)
- "Set the variable named by SYMBOL-NAME-PAIR to value. Make variable
- local first if LOCALFLAG not nil.
- SYMBOL-NAME-PAIR looks like (symbol-name . symbol-value)."
- (if localflag (make-local-variable (car pair)))
- (cond ((equal (car pair) t) nil) ; no-op on "t" or "nil"
- ((equal (car pair) nil) nil)
- (t (set (car pair) (tst-convert-object (cdr pair))))
- ) ; cond
- ) ; defun tst-achieve-sym
-
- (defun tst-convert-object (object)
- "Convert all descriptions of compound objects, e.g. markers,
- processes, windows, into the actual objects."
- (cond ((null object) object)
- ((vectorp object) object)
- ((atom object) object)
- ((equal (car object) 'marker) (tst-convert-marker object))
- ((equal (car object) 'process) (tst-convert-process object))
- ((equal (car object) 'window) nil) ; can't do anything here with window
- ((and (listp object)
- (atom (cdr object))
- (cdr object))
- ; object is a dotted pair
- (cons (tst-convert-object (car object))
- (tst-convert-object (cdr object))))
- ((listp object) (mapcar 'tst-convert-object object))
- (t object)
- ) ; cond
- ) ; defun tst-convert-object
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; processes
-
- (defun tst-achieve-processes-state (processes-desc)
- "Achieve processes captured in a state, but only if interactive."
- (message "Achieving state of processes...")
- (mapcar 'tst-convert-process processes-desc)
- ) ; tst-achieve-processes-state
-
- (defun tst-convert-process (process-desc)
- "Create the process described by PROCESS-DESC.
- PROCESS-DESC looks like (process (command (comstring argstrings))
- ;(exit-status 0) (filter filter-func) (name namestring)
- ;(sentinel sentinel-func) (status runstat))"
- (let (proc live procname)
- (setq procname (cadr (assoc 'name (cddr process-desc))))
- (setq live (and
- (car (read-from-string procname))
- (eq (process-status procname) 'run)))
- (if live
- (get-process (cadr (assoc 'name (cdr process-desc))))
- ; else
- (save-excursion
- (setq proc
- (apply 'start-process
- (cadr (assoc 'name (cdr process-desc)))
- (cadr (assoc 'buffer (cdr process-desc)))
- (cadr (assoc 'command (cdr process-desc)))
- ) ; apply
- ) ; setq
- (set-process-filter
- proc
- (cadr (assoc 'filter (cdr process-desc))))
- (set-process-sentinel
- proc
- (cadr (assoc 'sentinel (cdr process-desc))))
- ;;; (set-marker
- ;;; (process-mark proc)
- ;;; (cadr (assoc 'position
- ;;; (cadr (assoc 'process-mark (cdr process-desc)))))
- ;;; (process-buffer proc))
- proc
- ) ; save-excursion
- ) ; if
- ) ; let
- ) ; defun tst-convert-process
-
- (defun tst-convert-marker (marker-desc)
- "Create the marker described by MARKER-DESC.
- MARKER-DESC looks like (marker (position 23) (buffer bufname)).
- Bufname is a string, and the list (buffer bufname) may be nil if no
- buffer is associated."
- (set-marker (make-marker)
- (cadr (assoc 'position (cdr marker-desc)))
- (if (null (cadr (assoc 'buffer (cdr marker-desc)))) nil
- (get-buffer (cadr (assoc 'buffer (cdr marker-desc)))))
- ) ; set-marker
- ) ; defun tst-convert-marker
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; buffers
-
- (defun tst-achieve-bufs-state (bufs-states)
- "Achieve the buffer states as saved in BUFS-STATES.
- See tst-capture-buffers-state for definition of BUFS-STATES.
- If tst-achieve-buffers-nondestructively is t, buffers not in state are
- not killed."
- ; Local Variables
- (let ((state-buf-list) (buf-list))
-
- ;; setup each buffer that's in bufs-states
- (message "Achieving state of buffers...")
- (mapcar 'tst-achieve-buf-state bufs-states)
-
- ;; delete superfluous buffers
- (setq state-buf-list (mapcar 'tst-state-get-buf-name bufs-states))
- (setq buf-list (mapcar 'buffer-name (buffer-list)))
- (if (and (boundp tst-achieve-buffers-nondestructively)
- tst-achieve-buffers-nondestructively)
- nil
- ;; else
- (while buf-list
- (if (not (member (car buf-list) state-buf-list))
- (progn
- (kill-buffer (car buf-list))
- (message (concat "Killing buffer " (car buf-list) "...")))
- (setq buf-list (cdr buf-list))
- ) ; if
- ) ; while
- ) ; if
- ) ; let
- ) ; defun tst-achieve-bufs-state
-
-
- (defun tst-achieve-buf-state (buf-state)
- "Achieve the buffer state in BUF-STATE. See tst-capture-buffer-state
- for definition of BUF-STATE."
- ; Local Variables
- (let ()
- ; create buffer, set file
- (set-buffer (get-buffer-create (cadr (assoc 'buf-state-name buf-state))))
- (set-visited-file-name (cadr (assoc 'buf-state-file buf-state)))
-
- ; clear buffer contents and refill
- (if buffer-read-only (toggle-read-only))
- (delete-region (point-min) (point-max))
- (insert (cadr (assoc 'buf-state-contents buf-state)))
-
- ; set point and mark
- (set-mark (cadr (assoc 'buf-state-mark buf-state)))
- (goto-char (cadr (assoc 'buf-state-point buf-state)))
-
- ; set buffer flag(s)
- (set-buffer-modified-p (cadr (assoc 'buf-state-modified buf-state)))
-
- ; set local variables
- (kill-all-local-variables)
- (tst-achieve-local-vars (cadr (assoc 'buf-state-local-vars buf-state)))
- (use-local-map (cadr (assoc 'buf-state-local-map buf-state)))
- ) ; let
- ) ; defun tst-achieve-buf-state
-
- (defun tst-achieve-local-vars (pairs)
- "Take list of (VARIABLE . VALUE) pairs and makes local variables
- initialized to the value."
- (let ((localflag t))
- (mapcar
- ; the lambda here allows
- ; mapcar to pass a second
- ; argument localflag to
- ; function tst-achieve-sym
- ; while applying it to every
- ; element in list pairs
- '(lambda (pair)
- (tst-achieve-sym pair localflag))
- pairs)
- ) ; let
- ) ; defun tst-achieve-local-vars
-
- (defun tst-state-get-buf-name (bufstate)
- "Get name of buffer from BUFSTATE. See tst-capture-buffer-state for
- definition fo BUFSTATE."
- (cadr (assoc 'buf-state-name bufstate))
- ) ; defun tst-state-get-buf-name
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; windows
-
- (defun tst-achieve-windows-state (wstates)
- "Set the state of all windows to that described in the input list"
- (let ((sibling) (leftc-edges))
- (if (assoc 'split wstates)
- (progn
- (setq leftc-edges
- (cadr (assoc 'window-edges
- (car (cadr (assoc 'children wstates))))))
- (if (equal 'h (cadr (assoc 'split wstates)))
- (split-window-horizontally
- (-
- (cadr (cdr leftc-edges))
- (car leftc-edges)
- )
- )
- ;else vertical split
- (split-window-vertically
- (-
- (cadr (cddr leftc-edges))
- (cadr leftc-edges)
- )
- )
- ) ;if
- (setq sibling (next-window))
- ;descend to the left child
- (tst-achieve-windows-state (car (cadr (assoc 'children wstates))))
- ;go to the right child and achieve that
- (select-window sibling)
- (tst-achieve-windows-state
- (cadr (cadr (assoc 'children wstates))))
- ) ;progn
- (tst-achieve-window-state wstates)
- ) ;if assoc splits...
- ) ;let
- ) ;defun
-
- (defun tst-achieve-window-state (wstate)
- "Set the state of the current window to that discribed in the input
- a-list"
- (let ()
- (set-window-buffer (selected-window) (cadr (assoc 'window-buffer wstate)))
- (set-window-point (selected-window) (cadr (assoc 'window-point wstate)))
- (set-window-start (selected-window) (cadr (assoc 'window-start wstate)))
- ) ;let
- ) ;defun tst-achieve-window-state
-
- (defun tst-find-cur-window (wstates)
- "Given an input list of WINDOW STATES, find the one that is the current
- window of the of the state. This window has the attribute 'current-window
- set to t. Return t when this window is found."
- (let ()
- (if (assoc 'children wstates) ;if is is a compound window
- ; descend down the left subtree
- (if (not (tst-find-cur-window (car (cadr (assoc 'children wstates)))))
- ;now only descend down right subtree if left was unsuccessful
- (tst-find-cur-window (cadr (cadr (assoc 'children wstates))))
- ) ;if goto-cur...
- ; if it is a single window go to it if current-window is true
- (if (cadr (assoc 'current-window wstates))
- (tst-goto-described-window wstates)
- ) ;if assoc 'current-window
- ) ;if assoc 'children...
- ) ;let
- ) ;defun
-
- (defun tst-goto-described-window (wstate)
- "Given an input WINDOW STATE, cycle through existing windows until we
- settle in the one with edges of the one described in the state"
- (let ()
- (while (not (equal (window-edges (selected-window))
- (cadr (assoc 'window-edges wstate))
- )
- )
- (select-window (next-window))
- ) ;while
- ) ;let
- ) ;defun tst-goto-described-window
-
-