weiner@novavax.UUCP (Bob Weiner) (09/26/89)
The wealth of generally useful GNU Emacs lisp code posted to this group
has dried up recently. I thought I would start the flow again with this
posting.
This represents a prototype of a package that I never finished but that
became useful enough that I decided to post it. The active code works
well, the unfinished parts are commented out and may be disregarded
unless you would like to extend the package. Since it was a prototype,
the actual implementation has not been optimized at all.
Basically, it restores all buffers including major-modes, point
positions, and visible region bounds between sessions, giving you a
working context from day to day. Note also the 'emc-start-file'
variable which may specify the first file that you always want to see in
an Emacs session (set it in your own init file).
Enjoy.
;;
;; FILE: em-config.el
;; SUMMARY: Save and restore Emacs configurations between sessions.
;; USAGE: GNU Emacs Lisp Library
;;
;; AUTHOR: Bob Weiner
;; ORG: Motorola, Inc., Communications Sector, Applied Research
;; E-MAIL: USENET: weiner@novavax.UUCP
;;
;; ORIG-DATE: 22-Aug-89 at 16:07:48
;; LAST-MOD: 25-Sep-89 at 17:42:37 by Bob Weiner
;;
;; Copyright (C) 1989 Bob Weiner and Free Software Foundation, Inc.
;; Available for use and distribution under the same terms as GNU Emacs.
;;
;; This file is not part of GNU Emacs.
;;
;; DESCRIPTION:
;;
;; Currently saves only unmodified buffers visiting files. Also
;; saves only limited information about buffers. It may not work
;; properly with subsystem buffers that visit files. It is best to
;; kill these before saving a configuration.
;;
;; The exceptions are that:
;; An Info buffer is handled properly, so it need not be deleted.
;; Any buffer in rmail-mode is not saved. Thus, when 'rmail' is
;; invoked it works properly.
;;
;; To enable reading of Emacs state from last session at the start
;; of a new session, put the following in your personal Emacs init file:
;;
;; (load-library "em-config")
;; (emc-restore)
;;
;; Follow the above with this code to enable saving of Emacs state
;; when quitting a session:
;;
;; (defun save-buffers-kill-emacs (&optional arg)
;; "Offer to save each buffer, save file configuration, then kill this Emacs fork.
;; With prefix arg, silently save all file-visiting buffers, then kill."
;; (interactive "P")
;; (save-some-buffers arg t)
;; (emc-save)
;; (kill-emacs))
;;
;; DESCRIP-END.
(defconst emc-file "~/.em-config"
"Default file into which to save Emacs session data.")
(defconst emc-start-file nil
"Last file to read in each time the default Emacs configuration is loaded.
This makes it the first file seen by the user.")
(defun emc-save ()
(interactive)
(let ((standard-output (set-buffer (find-file-noselect emc-file))))
(erase-buffer)
;;; (emc-save-session-data)
(emc-save-buffer-data)
;;; (emc-save-window-data)
(set-buffer standard-output)
(save-buffer)
))
(defun emc-restore (&optional file)
"Restore emacs configuration from optional FILE or 'emc-file'.
Adds buffers to current buffer list. Returns t if the file is found,
otherwise nil."
(interactive)
(or file (setq file emc-file))
(if (file-exists-p file)
(let ((standard-input (set-buffer (find-file-noselect emc-file))))
(goto-char (point-min))
;;; (emc-restore-session-data)
(emc-restore-buffer-data)
;;; (emc-restore-window-data)
(kill-buffer standard-input)
(and emc-start-file (equal file emc-file)
(file-exists-p emc-start-file) (find-file emc-start-file))
t)))
(defun buffer-major-mode= (buf mode)
(eq (cdr (assq 'major-mode (buffer-local-variables buf))) mode))
(defun emc-save-buffer-data ()
;; Save only buffers visiting files; skip some in special modes.
(let ((buf-list (mapcar '(lambda (buf)
(let ((bn (buffer-name buf)))
(if (and (not (buffer-major-mode= buf 'Info-mode))
(or (null (buffer-file-name buf))
(string-match "^[ \*].*\*$" bn)
(buffer-major-mode= buf 'rmail-mode)
(equal bn (buffer-name
standard-output))))
nil
bn)))
(reverse (buffer-list)))))
(print buf-list)
(mapcar '(lambda (buf)
(if (null buf)
nil
(set-buffer buf)
(if (eq major-mode 'Info-mode)
(progn (print major-mode)
(print Info-current-file)
(print Info-current-node)
(print (point)))
(print major-mode)
(print (buffer-name))
(print (buffer-file-name))
(print buffer-read-only)
(print (point))
(print (point-min))
(print (point-max)))
))
buf-list)
))
(defun emc-restore-buffer-data ()
(let ((buf-list (read))
(buf-name) (file) (mode)
(buf-read-only) (point)
(point-min) (point-max)
(mark-list))
(mapcar '(lambda (buf)
(if (null buf)
nil
(setq mode (read))
(if (eq mode 'Info-mode)
(progn (info)
(Info-find-node (read) (read))
(goto-char (read)))
(setq buf-name (read)
file (read)
buf-read-only (read)
point (read)
point-min (read)
point-max (read))
(if (file-exists-p file)
(progn (find-file file)
(setq buffer-name buf-name
buffer-read-only buf-read-only)
(and mode (funcall mode))
(if (<= point (point-max))
(goto-char point))
(if (<= point-max (point-max))
(narrow-to-region point-min point-max)))))))
buf-list)
;;
;; Might want to do stuff and set buffer local variables from src/buffer.c.
;;
))
;;; Often won't work properly when used with an external window system.
;;;
;;; (defun emc-save-session-data ()
;;; (print (screen-height))
;;; (print (screen-width))
;;; )
;;;
;;; (defun emc-restore-session-data ()
;;; (set-screen-height (read))
;;; (set-screen-width (read)))
;;; Not finished; emc-save-window-data does not seem to work properly.
;;;
;;; (defun emc-save-window-data ()
;;; (let ((first-window (selected-window))
;;; (curr-window)
;;; (again t))
;;; (set-buffer standard-output)
;;; (goto-char (point-max))
;;; (select-window first-window)
;;; (while again
;;; (let ((bn (buffer-name)))
;;; (if (or (string-match "^[ \*].*\*$" bn)
;;; (equal bn (buffer-name standard-output)))
;;; nil
;;; (print (buffer-file-name))
;;; (print (buffer-name))
;;; (print (window-edges))
;;; (print (window-point))
;;; (print (window-start))
;;; (print (window-hscroll))))
;;; (select-window (setq curr-window (next-window nil 1)))
;;; (setq again (not (eq curr-window first-window))))))
;;;
;;; (defun emc-restore-window-data (buf)
;;; (let ((standard-input buf))
;;; (find-file (read buf))
;;; (setq buffer-name (read buf))
;;; ;; (read <window-edges>)
;;; (set-window-point (read buf))
;;; (set-window-start (read buf))
;;; (set-window-hscroll (read buf))))
;;;
;; TO DO: save window configs ring
(provide 'em-config)
--
Bob Weiner, Motorola, Inc., USENET: ...!gatech!uflorida!novavax!weiner
(407) 738-2087bob@MorningStar.COM (Bob Sutterfield) (09/27/89)
In article <1502@novavax.UUCP> weiner@novavax.UUCP (Bob Weiner) writes:
The wealth of generally useful GNU Emacs lisp code posted to this
group has dried up recently.
That's probably because it's mostly moved over to gnu.emacs/info-gnu-emacs.
I thought I would start the flow again with this posting.
Bravo!