1 ;;; wconfig.el --- Saves and yanks from save ring of window configurations.
3 ;; Copyright (C) 1989-1995, Free Software Foundation, Inc.
4 ;; Developed with support from Motorola Inc.
6 ;; Author: Bob Weiner, Brown U.
7 ;; Maintainer: Mats Lidell <matsl@contactor.se>
8 ;; Keywords: frames, hypermedia
10 ;; This file is part of GNU Hyperbole.
12 ;; GNU Hyperbole is free software; you can redistribute it and/or
13 ;; modify it under the terms of the GNU General Public License as
14 ;; published by the Free Software Foundation; either version 3, or (at
15 ;; your option) any later version.
17 ;; GNU Hyperbole is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ;; General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301, USA.
29 ;; This library provides two unrelated means of managing window
30 ;; configurations, (the set of windows and associated buffers within a
31 ;; frame). The first means associates a name with each stored window
32 ;; configuration. The name can then be used to retrieve the window
33 ;; configuration later. The following functions provide this behavior:
35 ;; wconfig-add-by-name
36 ;; wconfig-delete-by-name
37 ;; wconfig-restore-by-name
39 ;; The second means of window configuration management is through
40 ;; the use of a ring structure, just like the Emacs kill ring except
41 ;; the elements stored are window configurations instead of textual
42 ;; regions. These configurations are local for a frame so there is a
43 ;; ring of configurations for each frame. The following functions
44 ;; support storage and sequential retrieval of window
51 ;; None of this information is stored between Emacs sessions, so your
52 ;; window configurations will last only through a single session of use.
54 ;; Based in part on kill-ring code from simple.el.
60 ;;; Recommended key bindings
63 ;;; Set up in local "hyperbole.el".
66 ;;; Other required Elisp libraries
76 (defconst wconfig-ring-max 10
77 "*Maximum length of window configuration ring before oldest elements are deleted.")
83 ;;; Handling of name associations with each stored window configuration.
85 (defun wconfig-add-by-name (name)
86 "Saves the current window configuration under the string NAME.
87 When called interactively and a window configuration already exists under
88 NAME, confirms whether or not to replace it."
89 (interactive "sName for current window configuration: ")
91 (error "(wconfig-add-by-name): NAME argument is not a string: %s" name))
92 (let ((set:equal-op (function (lambda (key elt)
93 (equal key (car elt))))))
94 (if (or (not (interactive-p))
95 (not (set:member name wconfig-names))
97 (format "Replace existing '%s' window configuration: " name)))
98 (progn (setq wconfig-names
99 (set:replace name (current-window-configuration)
102 (message "Window configuration '%s' saved. Use 'wconfig-restore-by-name' to restore." name))))))
105 (defun wconfig-delete-by-name (name)
106 "Deletes window configuration saved under NAME."
107 (interactive (list (hargs:read-match "Delete window configuration named: "
108 wconfig-names nil t)))
110 (error "(wconfig-delete-by-name): NAME argument is not a string: %s" name))
111 (let ((set:equal-op (function (lambda (key elt)
112 (equal key (car elt))))))
113 (setq wconfig-names (set:remove name wconfig-names))))
116 (defun wconfig-restore-by-name (name)
117 "Restores window configuration saved under NAME."
118 (interactive (list (hargs:read-match "Restore window configuration named: "
119 wconfig-names nil t)))
121 (error "(wconfig-restore-by-name): NAME argument is not a string: %s" name))
122 (let ((wconfig (set:get name wconfig-names)))
124 (set-window-configuration wconfig)
125 (error "(wconfig-restore-by-name): No window configuration named '%s'" name))))
127 ;;; Window configuration ring management (like text kill ring).
129 (defun wconfig-delete-pop ()
130 "Replaces current window config with most recently saved config in ring.
131 Then deletes this new configuration from the ring."
133 (let ((ring (wconfig-get-ring)))
134 (if (ring-empty-p ring)
135 (error "(wconfig-delete-pop): Window configuration save ring is empty")
137 (if (ring-empty-p ring)
138 (message "(wconfig-delete-pop): Window configuration save ring is empty")
139 (set-window-configuration (ring-ref ring 0))))))
142 (defun wconfig-ring-save ()
143 "Saves the current window configuration onto the save ring.
144 Use {\\[wconfig-yank-pop]} to restore it at a later time."
146 (ring-insert (wconfig-get-ring) (current-window-configuration))
148 (message "Window configuration saved. Use 'wconfig-yank-pop' to restore.")))
151 (defun wconfig-yank-pop (n)
152 "Replaces current window config with prefix arg Nth prior one in save ring.
153 Interactively, default value of N = 1, meaning the last saved window
154 configuration is displayed.
156 The sequence of window configurations wraps around, so that after the oldest
157 one comes the newest one."
159 (let ((ring (wconfig-get-ring)))
160 (if (ring-empty-p ring)
161 (error "(wconfig-yank-pop): Window configuration save ring is empty")
162 (let ((prev (ring-remove ring (- 1 n))))
163 (ring-insert-at-beginning ring prev)
164 (set-window-configuration (ring-ref ring 0))))))
167 (defun wconfig-get-ring ()
168 (let* ((frame (selected-frame))
169 (ring (frame-property frame 'wconfig-ring)))
171 (set-frame-property frame 'wconfig-ring (setq ring (make-ring wconfig-ring-max))))
175 ;;; Private variables
178 (defvar wconfig-names (set:create)
179 "Set of (name . window-configuration) elements.")
181 (run-hooks 'wconfig-load-hook)
185 ;;; wconfig.el ends here