;;;;;;;;;;;;;;;;;;;;;;; -*- Mode: Emacs-Lisp -*- ;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; wicos.el ;; Save and restore multiple window configurations (wicos) within emacs. ;; ;; v1.43; 23 Apr 1993 ;; ;; Copyright 1993 Heikki Suopanki ;; ;; email: suopanki@phoenix.oulu.fi ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; This program is free software; you can redistribute it and/or modify ;;; it under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 1, or (at your option) ;;; any later version. ;;; ;;; This program is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; The GNU General Public License is available by anonymouse ftp from ;;; prep.ai.mit.edu in pub/gnu/COPYING. Alternately, you can write to ;;; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, ;;; USA. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; LCD Archive Entry: ;; wicos|Heikki T. Suopanki|suopanki@phoenix.oulu.fi| ;; Save and restore multiple window configurations within Emacs.| ;; 23-Apr-1993|1.43|~/misc/wicos.el.Z| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (provide 'wicos) (defvar wico-show-ml nil "*Shows the wico name or number in the mode line if t.") (defvar wico-multi-screens nil "*Better support in multi screen environment if t.") ;; set the mode line ;(if (not (listp (car global-mode-string))) ; (setq global-mode-string (list global-mode-string))) (or (assoc 'wico-show-ml global-mode-string) (setq global-mode-string (cons '(wico-show-ml wico-mode-line) global-mode-string))) (defvar wico-mode-line "Scratch" "*String that is shown in the mode line.") (defvar wico-buf-count 10 ;; this was unlimited, but I prefer it this way "*How many buffers are associated with each wico") (defvar wico-scratch-buffer "*scratch*") ;; you probably need not to change anything after this ;; but go ahead if you want (defvar wico-not-used t "*Nil if any of the wico functions has been used.") (defvar wico-confs (vector nil) "*Vector that contains the information about wico configurations." ) (defvar wico-open-wicos 1 "*How many wicos are used.") (defvar wico-this-wico 0 "*Current wico.") (defvar wico-recent-wico 0) (defvar wico-map (make-sparse-keymap) "*Keymap for wicos.") (fset 'wico-command-prefix wico-map) (define-key wico-map "c" 'wico-create-new) (define-key wico-map "k" 'wico-kill) (define-key wico-map "p" 'wico-previous) (define-key wico-map "n" 'wico-next) (define-key wico-map "w" 'wico-name-wico) (define-key wico-map "?" 'wico-help) (define-key wico-map "0" 'wico-jump-0) (define-key wico-map "1" 'wico-jump-1) (define-key wico-map "2" 'wico-jump-2) (define-key wico-map "3" 'wico-jump-3) (define-key wico-map "4" 'wico-jump-4) (define-key wico-map "5" 'wico-jump-5) (define-key wico-map "6" 'wico-jump-6) (define-key wico-map "7" 'wico-jump-7) (define-key wico-map "8" 'wico-jump-8) (define-key wico-map "9" 'wico-jump-9) (define-key wico-map "s" 'wico-save-current-wico) (define-key wico-map "r" 'wico-restore-wico) (define-key wico-map "z" 'wico-zap) (define-key wico-map "u" 'wico-unkill) ;; not really a mode, used only to show the help (defun wico-help-mode () "Wico keys: \\[wico-create-new] create a new wico \\[wico-kill] kill current wico \\[wico-previous] previous wico \\[wico-next] next wico \\[wico-name-wico] give wico a name \\[wico-jump-0] ....... } jump to wico # \\[wico-jump-9] \\[wico-help] show this help \\[wico-save-current-wico] save current configuration \\[wico-restore-wico] restore last saved configuration \\[wico-unkill] unkill a killed wico \\[wico-zap] resets the original config " (interactive) nil) (defun wico-current-window-configuration () (run-hooks 'wico-current-configuration-hook) (let ((count-buf 0) (buffer-list (list (buffer-name))) (point-list (list (point))) (win-config (current-window-configuration)) (origin-buffer (buffer-name)) (origin-window (selected-window))) (while (progn (other-window 1) (not (eq origin-window (selected-window)))) (setq point-list (cons (point) point-list))) (while (progn (bury-buffer) (and (not (eq origin-buffer (buffer-name))) (< (setq count-buf (1+ count-buf)) wico-buf-count))) (setq buffer-list (cons (buffer-name) buffer-list))) (set-window-configuration win-config) ;; back where we started (list win-config point-list buffer-list))) (defun wico-set-window-configuration (config-and-points) (let ((point-list (car (cdr config-and-points))) (buffer-list (car (cdr (cdr config-and-points)))) (origin nil)) (mapcar '(lambda(arg) (if (get-buffer arg) (switch-to-buffer arg))) buffer-list) (delete-other-windows) (set-window-configuration (car config-and-points)) (setq origin (selected-window)) (while (progn (other-window -1) (not (eq origin (selected-window)))) (goto-char (car point-list)) (setq point-list (cdr point-list))) (goto-char (car point-list))) (run-hooks 'wico-set-configuration-hook)) (defun wico-zap () "Set window config to the original config of current wico." (interactive) (if (not (wico-check)) (progn (wico-set-window-configuration (aref wico-confs wico-this-wico)) (wico-update)))) (defun wico-next () "Switch to next wico." (interactive) (if (not (wico-check)) (progn (aset wico-confs wico-this-wico (wico-current-window-configuration)) (if (= wico-this-wico (1- wico-open-wicos)) (setq wico-this-wico 0) (setq wico-this-wico (1+ wico-this-wico))) (wico-set-window-configuration (aref wico-confs wico-this-wico)) (wico-update)))) (defun wico-previous () "Switch to previous wico." (interactive) (if (not (wico-check)) (progn (aset wico-confs wico-this-wico (wico-current-window-configuration)) (if (= wico-this-wico 0) (setq wico-this-wico (1- wico-open-wicos)) (setq wico-this-wico (1- wico-this-wico))) (wico-set-window-configuration (aref wico-confs wico-this-wico)) (wico-update)))) (defun wico-save-current-wico () "Save the current configuration." (interactive) (if (not (wico-check)) (setq wico-stored (wico-current-window-configuration)))) (defun wico-restore-wico () "Switch to the configuration which has been saved last." (interactive) (if (not (wico-check)) (wico-set-window-configuration wico-stored))) (defun wico-create-new () "Open a new wico." (interactive) (if (not (wico-check)) (progn (if (>= wico-open-wicos (length wico-confs)) (wico-enlarge-vectors)) ;; make the vectors bigger (aset wico-confs wico-this-wico (wico-current-window-configuration)) (delete-other-windows) (switch-to-buffer wico-scratch-buffer) (setq wico-open-wicos (1+ wico-open-wicos)) (setq wico-this-wico (1- wico-open-wicos)) (aset wico-confs wico-this-wico (wico-current-window-configuration)) (wico-update)))) (defun wico-kill () "Kill the current wico." (interactive) (if (not (wico-check)) (cond ((= wico-open-wicos 1) (message "Only one wico, can't kill")) (t (let ((i wico-this-wico)) (while (< i (1- wico-open-wicos)) (aset wico-confs i (aref wico-confs (1+ i))) (setq i (1+ i))) (setq wico-killed-wico (wico-current-window-configuration)) (setq wico-open-wicos (1- wico-open-wicos)) (if (= wico-this-wico wico-open-wicos) (setq wico-this-wico (1- wico-this-wico))) (wico-set-window-configuration (aref wico-confs wico-this-wico)) (wico-update)))))) (defun wico-unkill() (interactive) (wico-create-new) (wico-set-window-configuration wico-killed-wico)) ;; (defun wico-jump-to (arg &optional non-ia) "Go to a specific wico." (if (not (wico-check)) (if (>= arg 0) (if (< arg wico-open-wicos) (progn (aset wico-confs wico-this-wico (wico-current-window-configuration)) (setq wico-recent-wico wico-this-wico) (setq wico-this-wico arg) (wico-set-window-configuration (aref wico-confs wico-this-wico)) (if (not non-ia) (wico-update))) (message "No wico %d" arg)) (message "No wico %d" arg)))) (defun wico-help () "Help about wico functions." (interactive) (with-output-to-temp-buffer "*Wico Help*" (princ (documentation 'wico-help-mode)) (print-help-return-message))) (defun wico-jump-0 () (interactive) (wico-jump-to 0)) (defun wico-jump-1 () (interactive) (wico-jump-to 1)) (defun wico-jump-2 () (interactive) (wico-jump-to 2)) (defun wico-jump-3 () (interactive) (wico-jump-to 3)) (defun wico-jump-4 () (interactive) (wico-jump-to 4)) (defun wico-jump-5 () (interactive) (wico-jump-to 5)) (defun wico-jump-6 () (interactive) (wico-jump-to 6)) (defun wico-jump-7 () (interactive) (wico-jump-to 7)) (defun wico-jump-8 () (interactive) (wico-jump-to 8)) (defun wico-jump-9 () (interactive) (wico-jump-to 9)) (defun wico-jump-recent () (interactive) (wico-jump-to wico-recent-wico)) (defun wico-update () "Update wico variables Most wico functions call this function." (interactive) (if wico-not-used (progn (setq wico-not-used nil) (run-hooks 'wico-hook))) (run-hooks 'wico-update-hook) ;; update the wico name in the mode line (if wico-show-ml (wico-update-mode-line))) (defun wico-update-mode-line () (setq wico-mode-line (format "[%d] " wico-this-wico))) (defun wico-check() "Check if the wico functions can be used, returns nil if everything is okay" ;; ;; if there's a minibuffer open, do nothing (if (= (minibuffer-depth) 0) nil (message "Minibuffer open, close it first!"))) ;; is this really a good way to do it??? (defun wico-enlarge-vectors () (setq wico-confs (vconcat wico-confs (vector nil)))) ;; and finally define some things (defvar wico-killed-wico (wico-current-window-configuration)) (defvar wico-stored (wico-current-window-configuration) "*Configuration which has beens saved last.") (aset wico-confs wico-this-wico (wico-current-window-configuration)) (wico-update-mode-line) ;; end