;;!emacs
;;
;; FILE:         wconfig.el
;; SUMMARY:      Saves and yanks from save ring of window configurations.
;; USAGE:        GNU Emacs Lisp Library
;;
;; AUTHOR:       Bob Weiner
;; ORG:          Brown U.
;;
;; ORIG-DATE:    15-Mar-89
;; LAST-MOD:     22-Oct-92 at 12:02:42 by Bob Weiner
;;
;; This file is part of Hyperbole.
;;
;; Copyright (C) 1989, 1992  Free Software Foundation
;; Available for use and distribution under the same terms as GNU Emacs.
;; Developed with support from Motorola Inc.
;;
;; DESCRIPTION:  
;;
;;   Based on kill-ring code from simple.el.
;;
;; DESCRIP-END.

;;; ************************************************************************
;;; Recommended key bindings
;;; ************************************************************************

;;; Set up in local "hsite.el".

;;; ************************************************************************
;;; Public variables
;;; ************************************************************************

(defconst wconfig-ring-max 10
  "*Maximum length of window configuration ring before oldest elements are deleted.")

;;; ************************************************************************
;;; Public functions
;;; ************************************************************************

(defun wconfig-delete-pop ()
  "Replaces current window config with most recently saved config in ring.
Then deletes this new configuration from the ring."
  (interactive)
  (if (not wconfig-ring)
      (error "Window configuration save ring is empty")
    (set-window-configuration (car wconfig-ring))
    (and (eq wconfig-ring wconfig-ring-yank-pointer)
	 (setq wconfig-ring-yank-pointer (cdr wconfig-ring)))
    (setq wconfig-ring (cdr wconfig-ring))))


(defun wconfig-ring-save ()
  "Saves the current window configuration onto the save ring.
Use {\\[wconfig-yank-pop]} to restore it at a later time."
  (interactive)
  (setq wconfig-ring (cons (current-window-configuration) wconfig-ring))
  (if (> (length wconfig-ring) wconfig-ring-max)
      (setcdr (nthcdr (1- wconfig-ring-max) wconfig-ring) nil))
  (setq wconfig-ring-yank-pointer wconfig-ring)
  (wconfig-rotate-yank-pointer (1- (length wconfig-ring-yank-pointer)))
  (message "Window configuration saved.  Use 'wconfig-yank-pop' to restore."))

(defun wconfig-rotate-yank-pointer (arg)
  "Rotates the yanking point prefix ARG elements in the window configuration save ring.
Interactively, default value of ARG = 1."
  (interactive "p")
  (let ((length (length wconfig-ring)))
    (if (zerop length)
	(error "Window configuration save ring is empty")
      (setq wconfig-ring-yank-pointer
	    (nthcdr (% (+ arg (- length (length wconfig-ring-yank-pointer)))
		       length)
		    wconfig-ring)))))

(defun wconfig-yank-pop (n)
  "Replaces current window config with prefix arg Nth prior one in save ring.
Interactively, default value of N = 1, meaning the last saved window
configuration is displayed.

The sequence of window configurations wraps around, so that after the oldest
one comes the newest one."
  (interactive "p")
  (wconfig-rotate-yank-pointer n)
  (set-window-configuration (car wconfig-ring-yank-pointer)))

;;; ************************************************************************
;;; Private variables
;;; ************************************************************************

(defvar wconfig-ring nil
  "List of saved window configurations.")

(defvar wconfig-ring-yank-pointer nil
  "The tail of the window configuration ring whose car is the last thing yanked.")

(run-hooks 'wconfig-load-hook)

(provide 'wconfig)
