From 0d342f0aee3f2f800e486c0051dabe718a7b2841 Mon Sep 17 00:00:00 2001 From: Tom Willemsen Date: Wed, 23 Mar 2011 11:14:27 +0100 Subject: I don't like nxhtml --- emacs.d/nxhtml/util/winsav.el | 1585 ----------------------------------------- 1 file changed, 1585 deletions(-) delete mode 100644 emacs.d/nxhtml/util/winsav.el (limited to 'emacs.d/nxhtml/util/winsav.el') diff --git a/emacs.d/nxhtml/util/winsav.el b/emacs.d/nxhtml/util/winsav.el deleted file mode 100644 index 771f6ce..0000000 --- a/emacs.d/nxhtml/util/winsav.el +++ /dev/null @@ -1,1585 +0,0 @@ -;;; winsav.el --- Save and restore window structure -;; -;; Author: Lennart Borgman -;; Created: Sun Jan 14 2007 -(defconst winsav:version "0.77") ;;Version: 0.77 -;; Last-Updated: 2009-08-04 Tue -;; Keywords: -;; Compatibility: -;; -;; Features that might be required by this library: -;; -;; None -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Commentary: -;; -;; This library contains both user level commands and options and -;; functions for use in other elisp libraries. -;; -;;;; User level commands and options -;; -;; The user level commands and options are for saving frame, windows -;; and buffers between Emacs sessions. To do that you can customize -;; the options `desktop-save-mode' and `winsav-save-mode' or put this -;; at the end of your .emacs: -;; -;; (desktop-save-mode 1) -;; (winsav-save-mode 1) -;; -;; You can also save configurations that you later switch between. -;; For more information see the command `winsav-save-mode'. -;; -;; (There is also a command in this library for rotating window -;; borders in a frame, `winsav-rotate'. It is here just because the -;; needed support functions lives here.) -;; -;; -;; -;;;; Commands for other elisp libraries -;; -;; This library was orignally written to solve the problem of adding a -;; window to the left of some windows in a frame like the one below -;; -;; ___________ -;; | | | -;; | 1 | 2 | -;; |____|____| -;; | | -;; | 3 | -;; |_________| -;; -;; so that the window structure on the frame becomes -;; -;; ___________ -;; | | | | -;; | | 1| 2 | -;; | B|__|___| -;; | A| | -;; | R| 3 | -;; |__|______| -;; -;; -;; This problem can be solved by this library. However the solution in -;; this library is a bit more general: You first copy the window -;; structure and then restore that into another window. To do the -;; above you first copy the window structure in the first frame above -;; with `winsav-get-window-tree'. Then you create windows like this: -;; -;; ___________ -;; | | | -;; | | | -;; | B| | -;; | A| | -;; | R| | -;; |__|______| -;; -;; -;; Finally you use `winsav-put-window-tree' to put the window -;; structure into the right window. (Of course you could have put BAR -;; above, under etc.) -;; -;; -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; Bugs and limitations: -;; -;; Juanma Barranquero has pointed out there is a serious limitation in -;; this way of doing it when overlays with 'window properties are -;; used. The problem is that any pointers to windows are made invalid -;; since they are deleted. So in fact any code that relies on saved -;; pointers to windows will have problem if the window is one of those -;; that are involved here. -;; -;; To overcome this problem when doing something like inserting a BAR -;; window (see above) a new window has to be inserted in the existing -;; window tree on a frame in a way that is currently not supported in -;; Emacs. -;; -;; It would be nice to be have primitives to manipulate the window -;; tree more generally from elisp. That requires implementation of -;; them at the C level of course. -;; -;; However it is probably much easier to implement it quite a bit less -;; general. The concept of splitting is maybe then the right level to -;; search for primitives at. -;; -;; My conclusion is that it will take some time to find suitable -;; primitives for this. -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Change log: -;; -;; Version 0.72: -;; -;; - Format of window structure changed in Emacs 23. Adopted to that. -;; - Added save and restore of frame/window configurations between -;; Emacs sessions. -;; - Added named winsav configurations for save and restore of frames, -;; windows, buffers and files. -;; -;; Version 0.71: -;; -;; - Added rotation of window structure. -;; -;; Version 0.70: -;; -;; - Support for save and restore from file. -;; -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; 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 2, 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. -;; -;; You should have received a copy of the GNU General Public License -;; along with this program; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Code: - - -(eval-when-compile (require 'cl)) -(eval-and-compile (require 'desktop)) - -;; (defun winsav-upper-left-window(&optional frame w) -;; (let* ((tree (if w w (car (window-tree frame)))) -;; (is-split (not (windowp tree)))) -;; (if (not is-split) -;; tree -;; (winsav-upper-left-window frame (nth 2 tree))))) - - -(defcustom winsav-after-get-hook nil - "Hook to run after at the end of `winsav-get-window-tree'. -The functions in this hook are called with one parameter which is -the same as the return value from the function above." - :type 'hook - :group 'winsav) - -(defcustom winsav-after-put-hook nil - "Hook to run after at the end of `winsav-put-window-tree'. -The functions in this hook are called with one parameter which is -a list where each element is a list \(old-win new-win) where -OLD-WIN are the window from `winsav-get-window-tree' and NEW-WIN -is the newly created corresponding window. This list is the same -as the return value from the function above." - :type 'hook - :group 'winsav) - -(defun winsav-get-window-tree(&optional frame) - "Get window structure. -This returns an object with current windows with values, buffers, -points and the selected window. - -FRAME is the frame to save structure from. If nil use selected. - -At the very end of this function the hook `winsav-after-get' is -run." - ;;(let* ((upper-left (winsav-upper-left-window frame)) - (let* ((upper-left (frame-first-window frame)) - (num -1) - sel-num) - (dolist (w (window-list frame nil upper-left)) - (setq num (1+ num)) - (when (eq w (selected-window)) - (setq sel-num num))) - (let ((ret (list sel-num - (winsav-get-window-tree-1 frame nil)))) - (run-hook-with-args 'winsav-after-get-hook ret) - ret))) - -;; Fix-me: add window-hscroll -(defun winsav-get-window-tree-1(frame w) - (let ((tree (if w w (car (window-tree frame))))) - (if (windowp tree) - ;; Note: Desktop is used for saving buffers. - (with-current-buffer (window-buffer tree) - (list (window-buffer tree) - ;; buffer - (buffer-name) - (buffer-file-name) - ;;buffer-read-only - ;;(if mumamo-multi-major-mode mumamo-multi-major-mode major-mode) - ;;minor-modes - ;;buffer locals - ;;(cons (+ 0 (mark-marker)) (mark-active)) - ;; window - (window-point tree) - (window-edges tree) - (window-scroll-bars tree) - (window-fringes tree) - (window-margins tree) - (window-hscroll tree) - ;; misc - (window-dedicated-p tree) - (when (fboundp 'window-redisplay-end-trigger) - (window-redisplay-end-trigger tree)) - (window-start tree) - tree)) - (let* ((dir (nth 0 tree)) - (split (nth 1 tree)) - (wt (cddr tree)) - (wsubs (mapcar (lambda(wc) - (winsav-get-window-tree-1 nil wc)) - wt))) - (append (list dir split) wsubs))))) - -;;;###autoload -(defun winsav-put-window-tree (saved-tree window &optional copy-win-ovl win-ovl-all-bufs) - "Put window structure SAVED-TREE into WINDOW. -Restore a structure SAVED-TREE returned from -`winsav-get-window-tree' into window WINDOW. - -If COPY-WIN-OVL is non-nil then overlays having a 'window -property pointing to one of the windows in SAVED-TREE where this -window still is shown will be copied to a new overlay with -'window property pointing to the corresponding new window. - -If WIN-OVL-ALL-BUFS is non-nil then all buffers will be searched -for overlays with a 'window property of the kind above. - -At the very end of this function the hook `winsav-after-put' is -run." - (let* ((sel-num (nth 0 saved-tree)) - (tree (nth 1 saved-tree)) - nsiz - nh - nw - osiz - oh - ow - scale-w - scale-h - first-win - winsav-put-return) - (unless (or (bufferp (car tree)) - (eq 'buffer (car tree))) - (setq nsiz (window-edges window)) - (setq nh (- (nth 3 nsiz) (nth 1 nsiz))) - (setq nw (- (nth 2 nsiz) (nth 0 nsiz))) - (setq osiz (cadr tree)) - (setq oh (- (nth 3 osiz) (nth 1 osiz))) - (setq ow (- (nth 2 osiz) (nth 0 osiz))) - (setq scale-w (unless (= ow nw) (/ nw (float ow)))) - (setq scale-h (unless (= oh nh) (/ nh (float oh))))) - (setq first-win (winsav-put-window-tree-1 tree window scale-w scale-h t 1)) - (select-window first-win) - (when sel-num (other-window sel-num)) - (winsav-fix-win-ovl winsav-put-return copy-win-ovl win-ovl-all-bufs) - (run-hook-with-args 'winsav-after-put-hook winsav-put-return) - winsav-put-return)) - -(defun winsav-put-window-tree-1 (saved-tree window scale-w scale-h first-call level) - "Helper for `winsav-put-window-tree'. -For the arguments SAVED-TREE and WINDOW see that function. - -The arguments SCALE-W and SCALE-H are used to make the saved -window config fit into its new place. FIRST-CALL is a state -variable telling if this is the first round. LEVEL helps -debugging by tells how far down we are in the call chain." - (if (or (bufferp (car saved-tree)) - ;;(not (car saved-tree)) - (eq 'buffer (car saved-tree)) - ) - (let ((buffer (nth 0 saved-tree)) - ;; buffer - (bufnam (nth 1 saved-tree)) - (filnam (nth 2 saved-tree)) - ;;(mark (nth 3 saved-tree)) - ;; window - (point (nth 3 saved-tree)) - (edges (nth 4 saved-tree)) - (scroll (nth 5 saved-tree)) - (fringe (nth 6 saved-tree)) - (margs (nth 7 saved-tree)) - (hscroll (nth 8 saved-tree)) - (dedic (nth 9 saved-tree)) - (trigger (nth 10 saved-tree)) - (start (nth 11 saved-tree)) - (ovlwin (nth 12 saved-tree)) - scr2 - (misbuf " *Winsav information: Buffer is gone*")) - (or (windowp ovlwin) - (not ovlwin) - (error "Parameter mismatch, ovlwin not window: %s" ovlwin)) - (when first-call - (add-to-list 'winsav-put-return (list ovlwin window)) - (when (eq 'buffer buffer) - (when filnam - (setq buffer (winsav-find-file-noselect filnam))) - (if (buffer-live-p buffer) - (or (string= bufnam (buffer-name buffer)) - (eq (string-to-char bufnam) 32) ;; Avoid system buffer names - (rename-buffer bufnam)) - (when (eq (string-to-char bufnam) 32) - (setq bufnam " *Winsav dummy buffer*")) - ;; Fix-me, this might need some tweaking: Don't restore - ;; buffers without a file name and without - ;; content. (desktop-mode will make that when - ;; necessary.) Just show the scratch buffer instead. - (setq buffer (get-buffer bufnam)) - (unless (and buffer - (< 0 (buffer-size buffer))) - (setq buffer (get-buffer-create "*scratch*"))))) - (set-window-buffer window buffer) - (set-window-dedicated-p window dedic) - ;; Strange incompatibility in scroll args: - (setq scr2 (list (nth 0 scroll) (nth 2 scroll) (nth 3 scroll))) - (apply 'set-window-scroll-bars (append (list window) scr2)) - (apply 'set-window-fringes (append (list window) fringe)) - (set-window-margins window (car margs) (cdr margs)) - (set-window-hscroll window hscroll) - (unless (>= emacs-major-version 23) - (with-no-warnings - (set-window-redisplay-end-trigger window trigger)))) - (let* ((nsiz (window-edges window)) - (nh (- (nth 3 nsiz) (nth 1 nsiz))) - (nw (- (nth 2 nsiz) (nth 0 nsiz))) - (osiz edges) ;(nth 2 saved-tree)) - (oh (- (nth 3 osiz) (nth 1 osiz))) - (ow (- (nth 2 osiz) (nth 0 osiz))) - (diff-w (- (if scale-w - (round (* scale-w ow)) - ow) - nw)) - (diff-h (- (if scale-h - (round (* scale-h oh)) - oh) - nh))) - ;; Avoid rounding naggings: - (when (> (abs diff-h) 1) - (bw-adjust-window window diff-h nil)) - (when (> (abs diff-w) 1) - (bw-adjust-window window diff-w t))) - ;; Fix-me: there were some problems getting point correctly. Don't know why... - (with-selected-window window - (with-current-buffer (window-buffer window) - (goto-char point)) - (set-window-point window point) - ;;(unless (buffer-live-p buffer) (setq point 1) (setq start 1)) - (set-window-start window start) - ;; Maybe point got off screen? - (when (/= point (window-point window)) - (set-window-point window point))) - window) - (let* ((ver (car saved-tree)) - (wtree (list (cons window (caddr saved-tree)))) - (nwin window) - pwin - pdelta - (first-win nwin)) - ;; First split to get it in correct order - (when first-call - (dolist (subtree (cdddr saved-tree)) - (setq pwin nwin) - ;;(message "nwin edges=%s, ver=%s" (window-edges nwin) ver) - (let ((split-err nil) - (window-min-height 1) - (window-min-width 1)) - (setq nwin (split-window nwin nil (not ver)))) - ;; Make the previous window as small as permitted to allow - ;; splitting as many times as possible - (setq pdelta (- - (if ver - window-min-height - window-min-width) - (if ver - (window-width pwin) - (window-height pwin)))) - ;;(message "pwin=%s, edges=%s, pdelta=%s, ver=%s" pwin (window-edges pwin) pdelta ver) - ;; No reason to fail here: - (condition-case err - (adjust-window-trailing-edge pwin pdelta (not ver)) - (error - ;;(message "awt=>%s" (error-message-string err)) - nil - )) - ;; Add to traverse - (add-to-list 'wtree - (cons nwin subtree) - t))) - ;; Now traverse. Sizing is a bit tricky, multiple runs have to - ;; be done (as in balance-windows). - (let (tried-sizes - last-sizes - (windows (window-list (selected-frame)))) - (while (not (member last-sizes tried-sizes)) - (when last-sizes (setq tried-sizes (cons last-sizes tried-sizes))) - (setq last-sizes (mapcar (lambda (w) - (window-edges w)) - windows)) - (dolist (wsub (reverse wtree)) - (select-window (car wsub)) - (winsav-put-window-tree-1 (cdr wsub) (selected-window) - scale-w scale-h - first-call - (1+ level) - )) - (setq first-call nil) - )) - first-win))) - -(defun winsav-fix-win-ovl(win-list copy-win-ovl win-ovl-all-bufs) - (let ((oldwins (mapcar (lambda(elt) - (car elt)) - win-list)) - ovlwin - window) - (let (buffers) - (if win-ovl-all-bufs - (setq buffers (buffer-list)) - (mapc (lambda(w) - (when (window-live-p w) - (add-to-list 'buffers (window-buffer w)))) - oldwins)) - (dolist (buf buffers) - (with-current-buffer buf - (save-restriction - (widen) - (dolist (overlay (overlays-in (point-min) (point-max))) - (when (setq ovlwin (car (memq (overlay-get overlay 'window) oldwins))) - (setq window (cadr (assoc ovlwin win-list))) - ;; If the old window is still alive then maybe copy - ;; overlay, otherwise change the 'window prop. However - ;; copy only if COPY-WIN-OVL is non-nil. - (if (not (and (window-live-p ovlwin) - (window-frame ovlwin))) - (overlay-put overlay 'window window) - (when copy-win-ovl - (let* ((props (overlay-properties overlay)) - (start (overlay-start overlay)) - (end (overlay-end overlay)) - ;; Fix-me: start and end marker props - (newovl (make-overlay start end))) - (while props - (let ((key (car props)) - (val (cadr props))) - (setq props (cddr props)) - (when (eq key 'window) - (setq val window)) - (overlay-put newovl key val)))))))))))))) - - - -(defun winsav-transform-edges (edges) - "Just rotate the arguments in EDGES to make them fit next function." - (let ((le (nth 0 edges)) - (te (nth 1 edges)) - (re (nth 2 edges)) - (be (nth 3 edges))) - (list te le be re))) - -(defun winsav-transform-1 (tree mirror transpose) - "Mirroring of the window tree TREE. -MIRROR could be 'mirror-top-bottom or 'mirror-left-right which I -think explain what it does here. TRANSPOSE shifts the tree -between a horisontal and vertical tree." - (let* ((vertical (nth 0 tree)) - (edges (nth 1 tree)) - (subtrees (nthcdr 2 tree)) - ) - ;;(winsav-log "tree 1" tree) - (when transpose - (cond - ((eq vertical nil) - (setcar tree t)) - ((eq vertical t) - (setcar tree nil)) - (t - (error "Uh? vertical=%S" vertical)))) - (setcar (nthcdr 1 tree) (winsav-transform-edges edges)) - (dolist (subtree subtrees) - (if (bufferp (car subtree)) - (when transpose - (let ((edges (nth 4 subtree))) - ;;(winsav-log "subtree 1" subtree) - (setcar (nthcdr 4 subtree) (winsav-transform-edges edges)) - ;;(winsav-log "subtree 2" subtree) - )) - (winsav-transform-1 subtree mirror transpose))) - (when (case mirror - ('mirror-top-bottom vertical) - ('mirror-left-right (not vertical)) - (nil) ;; Don't mirror - (t - (error "Uh? mirror=%s" mirror))) - (setcdr (nthcdr 1 tree) (reverse subtrees)) - ) - )) - -(defun winsav-find-file-noselect (filename) - "Read file FILENAME into a buffer and return the buffer. -Like `find-file-noselect', but if file is not find then creates a -buffer with a message about that." - (let ((buf (find-file-noselect filename))) - (unless buf - (setq buf (generate-new-buffer filename)) - (with-current-buffer buf - (insert "Winsav could not find the file " filename) - (set-buffer-modified-p nil))) - buf)) - - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Session saving and restore etc - -;;;###autoload -(defgroup winsav nil - "Save frames and windows when you exit Emacs." - :group 'frames) - -;;;###autoload -(define-minor-mode winsav-save-mode - "Toggle winsav configuration saving mode. -With numeric ARG, turn winsav saving on if ARG is positive, off -otherwise. - -When this mode is turned on, winsav configurations are saved from -one session to another. A winsav configuration consists of -frames, windows and visible buffers configurations plus -optionally buffers and files managed by the functions used by -option `desktop-save-mode' - -By default this is integrated with `desktop-save-mode'. If -`desktop-save-mode' is on and `winsav-handle-also-desktop' is -non-nil then save and restore also desktop. - -See the command `winsav-switch-config' for more information and -other possibilities. - -Note: If you want to avoid saving when you exit just turn off -this minor mode. - -For information about what is saved and restored and how to save -and restore additional information see the function -`winsav-save-configuration'." - :global t - :group 'winsav) - -(defun winsav-save-mode-on () - "Ensable option `winsav-save-mode'. Provided for use in hooks." - (winsav-save-mode 1)) - -(defun winsav-save-mode-off () - "Disable option `winsav-save-mode'. Provided for use in hooks." - (winsav-save-mode -1)) - -(defcustom winsav-save 'ask-if-new - "Specifies whether the winsav config should be saved when it is killed. -A winsav config \(winsav frame configuration) is killed when the -user changes winsav directory or quits Emacs. - -Possible values are: - t -- always save. - ask -- always ask. - ask-if-new -- ask if no winsav file exists, otherwise just save. - ask-if-exists -- ask if winsav file exists, otherwise don't save. - if-exists -- save if winsav file exists, otherwise don't save. - nil -- never save. -The winsav config is never saved when the option `winsav-save-mode' is nil. -The variables `winsav-dirname' and `winsav-base-file-name' -determine where the winsav config is saved." - :type - '(choice - (const :tag "Always save" t) - (const :tag "Always ask" ask) - (const :tag "Ask if winsav file is new, else do save" ask-if-new) - (const :tag "Ask if winsav file exists, else don't save" ask-if-exists) - (const :tag "Save if winsav file exists, else don't" if-exists) - (const :tag "Never save" nil)) - :group 'winsav) - -(defcustom winsav-handle-also-desktop t - "If this is non-nil then desktop is also saved and restored. -See option `winsav-save-mode' for more information." - :type 'boolean - :group 'winsav) - -(defcustom winsav-base-file-name - (convert-standard-filename ".emacs.winsav") - "Base name of file for Emacs winsav, excluding directory part. -The actual file name will have a system identifier added too." - :type 'file - :group 'winsav) - -(defvar winsav-dirname nil - "The directory in which the winsav file should be saved.") - -(defun winsav-current-default-dir () - "Current winsav configuration directory." - (or winsav-dirname "~/")) - -;;(find-file (winsav-full-file-name)) -(defun winsav-default-file-name () - "Default winsav save file name. -The file name consist of `winsav-base-file-name' with a system -identifier added. This will be '-nw' for a terminal and '-' + -the value of `window-system' otherwise." - (let ((sys-id (if (not window-system) - "nw" - (format "%s" window-system)))) - (concat winsav-base-file-name "-" sys-id))) - -(defun winsav-full-file-name (&optional dirname) - "Return the full name of the winsav session file in DIRNAME. -DIRNAME omitted or nil means use `~'. - -The file name part is given by `winsav-default-file-name'." - ;; Fix-me: Different frames in different files? Can multi-tty be handled?? - (expand-file-name (winsav-default-file-name) (or dirname - (winsav-current-default-dir)))) - - - -(defun winsav-serialize (obj) - "Return a string with the printed representation of OBJ. -This should be possible to eval and get a similar object like OBJ -again." - ;;(message "winsav-serialize a") - (prin1-to-string obj) - ;;(message "winsav-serialize b") - ) - -(defcustom winsav-before-save-configuration-hook nil - "Hook called before saving frames. -Hook for writing elisp code at the beginning of a winsav -configuration file. When this hook is called the current buffer -and point is where the code should be written. - -This is a normal hook. For more information see -`winsav-save-configuration'." - :type 'hook - :group 'winsav) - -(defcustom winsav-after-save-configuration-hook nil - "Hook called after saving frames. -Hook for writing elisp code at the end of a winsav configuration -file. When this hook is called the current buffer and point is -where the code should be written. - -This is a normal hook. For more information see -`winsav-save-configuration'." - :type 'hook - :group 'winsav) - -(defcustom winsav-after-save-frame-hook nil - "Hook called when saving a frame after saving frame data. -Hook for writing elisp code in a winsav configuration file after -each frame creation. When this hook is called code for restoring -a frame has been written and code that sets -`winsav-last-loaded-frame' to point to it. Point is in the -configuration file buffer right after this. - -This is a normal hook. For more information see -`winsav-save-configuration'." - :type 'hook - :group 'winsav) - -(defvar winsav-loaded-frames nil) -(defvar winsav-last-loaded-frame nil) - -(defun winsav-restore-frame (frame-params - window-tree-params - use-minibuffer-frame - window-state - window-visible) - "Restore a frame with specified values. -If this is a minibuffer only frame then just apply the frame -parameters FRAME-PARAMS. Otherwise create a new frame using -FRAME-PARAMS and set up windows and buffers according to -WINDOW-TREE-PARAMS. Also, if USE-MINIBUFFER-FRAME let the new -frame have this minibuffer frame. - -WINDOW-STATE is 1 for minimized, 2 for normal and 3 for -maximized." - (let* ((default-minibuffer-frame use-minibuffer-frame) - (frame-name (cdr (assoc 'name frame-params))) - (minibuffer-val (cdr (assoc 'minibuffer frame-params))) - (minibuffer-only (eq 'only minibuffer-val)) - (mini-frames - (delq nil (mapcar (lambda (frm) - (when (eq 'only (frame-parameter frm 'minibuffer)) - frm)) - (frame-list)))) - (frame-with-that-name - (when (and frame-name minibuffer-only) - (catch 'frame - (dolist (frame (frame-list)) - (when (string= frame-name (frame-parameter frame 'name)) - (throw 'frame frame)))))) - ;; If this is a minibuffer only frame then if it is already - ;; there under a correct name then do not create it because - ;; there might be variables pointing to it; just set the - ;; parameters. Perhaps even better: if it is not already - ;; there give an error - because it might be impossible to - ;; set things up correctly then. - (frame-with-that-name-has-mini - (when frame-with-that-name - (eq 'only - (frame-parameter frame-with-that-name 'minibuffer)))) - (this-mini-frame (when minibuffer-only - (or frame-with-that-name - (and (= 1 (length mini-frames)) - (car mini-frames))))) - (create-new - (if minibuffer-only - (if this-mini-frame ;frame-with-that-name-has-mini - nil - (error "Winsav: Can't find minibuffer only frame with name %s" - frame-name)) - t)) - (this-frame (if create-new - (make-frame frame-params) - this-mini-frame)) - (win (frame-first-window this-frame))) - ;;(message "create-new=%s, frame-with-that-name=%s" create-new frame-with-that-name) - ;; (when was-max - ;; (winsav-set-maximized-size this-frame) - ;; ;; Wait for maximize to occur so horizontal scrolling gets ok. - ;; (sit-for 1.5) - ;; ) - (case window-state - (1 (winsav-set-minimized-state this-frame)) - (3 (winsav-set-maximized-state this-frame))) - (unless window-visible - (make-frame-invisible this-frame)) - (if create-new - (winsav-put-window-tree window-tree-params win) - (modify-frame-parameters this-frame frame-params)) - (setq winsav-last-loaded-frame this-frame) - (setq winsav-loaded-frames (cons this-frame winsav-loaded-frames)) - )) - -(defcustom winsav-frame-parameters-to-save - '( - ;;explicit-name - ;;name - ;;parent-id - ;;title - alpha - auto-lower - auto-raise - background-color - background-mode - border-color - border-width - buffer-predicate - cursor-color - cursor-type - font - font-backend - foreground-color - fullscreen - icon-name - icon-type - icon-left - icon-top - internal-border-width - left-fringe - line-spacing - menu-bar-lines - modeline - mouse-color - right-fringe - screen-gamma - scroll-bar-width - tool-bar-lines - top left width height - tty-color-mode ;; ?? - unsplittable - user-position - user-size - vertical-scroll-bars - visibility - ) - "Parameters saved for frames by `winsav-save-configuration'. -Parameters are those returned by `frame-parameters'." - :type '(repeat (symbol :tag "Frame parameter")) - :group 'winsav) - -(defun frame-visible-really-p (frame) - "Return t if FRAME is visible. -This tries to be more corrent on w32 than `frame-visible-p'." - (cond ((fboundp 'w32-frame-placement) - (< 0 (nth 4 (w32-frame-placement frame)))) - (t - (frame-visible-p frame)))) - -(defun frame-maximized-p (frame) - "Return t if it is known that frame is maximized." - (cond ((fboundp 'w32-frame-placement) - (= 3 (abs (nth 4 (w32-frame-placement frame))))) - (t nil))) - -(defun frame-minimized-p (frame) - "Return t if it is known that frame is minimized." - (cond ((fboundp 'w32-frame-placement) - (= 3 (abs (nth 4 (w32-frame-placement frame))))) - (t nil))) - -;;(winsav-set-restore-size nil) -;; (defun winsav-set-restore-size (frame) -;; (when (fboundp 'w32-send-sys-command) -;; (let ((cur-frm (selected-frame))) -;; (select-frame-set-input-focus frame) -;; (w32-send-sys-command #xf120) -;; ;; Note: sit-for must be used, not sleep-for. Using the latter -;; ;; prevents the fetching of the new size (for some reason I do not -;; ;; understand). -;; (sit-for 1.5) -;; (select-frame-set-input-focus cur-frm)) -;; t)) - -(defun winsav-set-maximized-state (frame) - (when (fboundp 'w32-send-sys-command) - (select-frame-set-input-focus frame) - (w32-send-sys-command #xf030) - (sit-for 1.0) - t)) - -(defun winsav-set-minimized-state (frame) - (when (fboundp 'w32-send-sys-command) - (select-frame-set-input-focus frame) - (w32-send-sys-command #xf020) - (sit-for 1.0) - t)) - -(defun winsav-save-frame (frame mb-frm-nr buffer) - "Write into buffer BUFFER elisp code to recreate frame FRAME. -If MB-FRM-NR is a number then it is the order number of the frame -whose minibuffer should be used." - (message "winsav-save-frame buffer=%s" buffer) - (message "winsav-save-frame buffer 2=%s" (current-buffer)) - (let* ((start nil) - (end nil) - (obj (winsav-get-window-tree frame)) - (dummy (message "winsav-save-frame buffer 3=%s" (current-buffer))) - (frm-size-now (cons (frame-pixel-height frame) - (frame-pixel-width frame))) - (dummy (message "winsav-save-frame buffer 4=%s" (current-buffer))) - (placement (when (fboundp 'w32-frame-placement) (w32-frame-placement frame))) - ;; (was-max (and frm-size-rst - ;; (not (equal frm-size-now frm-size-rst)))) - (window-state (abs (nth 4 placement))) - ;; (frm-size-rst (when (winsav-set-restore-size frame) - ;; (cons (frame-pixel-height frame) - ;; (frame-pixel-width frame)))) - ;;(frm-size-rst (when was-max)) - ;;(frm-size-rst (when (= 3 (abs (nth 4 placement))))) - (dummy (message "winsav-save-frame buffer 5=%s" (current-buffer))) - (frm-par (frame-parameters frame)) - (dummy (message "winsav-save-frame buffer 6=%s" (current-buffer))) - ) - (message "winsav-save-frame a1 cb=%s" (current-buffer)) - (with-current-buffer buffer - ;;(y-or-n-p (format "was-max=%s" was-max)) - (message "winsav-save-frame a2 cb=%s" (current-buffer)) - (setq frm-par - (delq nil - (mapcar (lambda (elt) - (cond - ((memq (car elt) winsav-frame-parameters-to-save) - elt) - ((eq (car elt) 'minibuffer) - (let ((val (cdr elt))) - (if (not (windowp val)) - elt - (if (eq (window-frame val) frame) - nil - (cons 'minibuffer nil))))))) - frm-par))) - (message "winsav-save-frame b cb=%s" (current-buffer)) - (insert "(winsav-restore-frame\n'" - ;;make-frame-params - (winsav-serialize frm-par)) - (message "winsav-save-frame b.0.1") - ;;window-tree-params - (setq start (point)) - (insert "'" (winsav-serialize obj) "\n") - (message "winsav-save-frame b.0.2") - (setq end (copy-marker (point) t)) - (message "winsav-save-frame b.0.3") - (message "winsav-save-frame b.1") - ;; (replace-regexp (rx "#"))) - ;; (1+ ">")) ;; 1+ for indirect buffers ... - ;; "buffer" - ;; nil start end) - (goto-char start) - (while (re-search-forward (rx "#"))) - (1+ ">")) ;; 1+ for indirect buffers ... - end t) - (replace-match "buffer" nil t)) - (message "winsav-save-frame b.2") - ;; (replace-regexp (rx "#"))) - ;; (1+ ">")) - ;; "nil" - ;; nil start end) - (goto-char start) - (while (re-search-forward (rx "#"))) - (1+ ">")) ;; 1+ for indirect buffers ... - end t) - (replace-match "nil" nil t)) - (message "winsav-save-frame c") - (goto-char end) - ;;use-minibuffer-frame - (insert (if mb-frm-nr - (format "(nth %s (reverse winsav-loaded-frames))" mb-frm-nr) - "nil") - (format " %s" window-state) - (if (frame-visible-really-p frame) " t " " nil ") - ")\n\n") - - (insert " ;; ---- before after-save-frame-hook ----\n") - ;; (dolist (fun winsav-after-save-frame-hook) - ;; (funcall fun frame (current-buffer))) - (run-hooks winsav-after-save-frame-hook) - (message "winsav-save-frame d") - (insert " ;; ---- after after-save-frame-hook ----\n") - - ;;(insert " )\n\n\n") - ))) - -(defvar winsav-file-version "1" - "Version number of winsav file format. -Written into the winsav file and used at winsav read to provide -backward compatibility.") - - -;; fix-me: This should be in desktop.el -;; Fix-me: incomplete, not ready. -(defun winsav-restore-indirect-file-buffer (file name) - "Make indirect buffer from file buffer visiting file FILE. -Give it the name NAME." - (let* ((fbuf (find-file-noselect file))) - (when fbuf - (make-indirect-buffer fbuf name)))) - -(defun winsav-save-indirect-buffers (to-buffer) - "Save information about indirect buffers. -Only file visiting buffers currently. Clone the base buffers." - (with-current-buffer to-buffer - (dolist (buf (buffer-list)) - (when (buffer-base-buffer buf) - (let* ((base-buf (buffer-base-buffer buf)) - (file (buffer-file-name base-buf))) - (when file - (insert "(winsav-restore-indirect-file-buffer \"" - file "\" \"" (buffer-name buf) "\")\n"))))))) - -;; Fix-me: test -;; (defun winsav-restore-minibuffer (frame-num frm-num win-num) -;; (let* ((frame (nth (1- frame-num) winsav-loaded-frames)) -;; (mini-frm (nth (1- frm-num) winsav-loaded-frames)) -;; (mini-win (nth (1- win-num) (reverse (window-list mini-frm)))) -;; ) -;; (with-selected-frame frame -;; (set-minibuffer-window mini-win)))) - -(defvar winsav-minibuffer-alist nil) -(defun winsav-save-minibuffers (sorted-frames to-buffer) - "Save information about minibuffer frames. -SORTED-FRAMES should be a list of all frames sorted using -`winsav-frame-sort-predicate'." - (with-current-buffer to-buffer - (setq winsav-minibuffer-alist nil) - (dolist (frame sorted-frames) - (let* ((num-frames (length sorted-frames)) - (mini-win (minibuffer-window frame)) - (mini-frm (window-frame mini-win)) - (win-num (length - (memq mini-win - (window-list mini-frm t (frame-first-window mini-frm))))) - (frm-num (- num-frames (length (memq mini-frm sorted-frames)))) - (frame-num (- num-frames (length (memq frame sorted-frames))))) - (unless (and (eq mini-frm frame) - (= win-num 1)) - ;; Not the normal minibuffer window - ;;(insert (format ";;(winsav-restore-minibuffer %s %s %s)\n" - ;;(insert (format "'(%s %s)\n" frame-num frm-num) - (setq winsav-minibuffer-alist (cons (list frame-num frm-num) winsav-minibuffer-alist)) - ))) - (insert "(setq winsav-minibuffer-alist '" - (winsav-serialize winsav-minibuffer-alist) - ")\n"))) - -(defun winsav-restore-dedicated-window (frame-num win-num dedicate-flag) - "Set dedicated window flag. -On frame number FRAME-NUM in `winsav-loaded-frames' set the -dedicated flag on window number WIN-NUM to DEDICATE-FLAG." - (let* ((frame (nth (1- frame-num) winsav-loaded-frames)) - (win (nth (1- win-num) (reverse (window-list frame t - (frame-first-window frame)))))) - (set-window-dedicated-p win dedicate-flag))) - -(defun winsav-save-dedicated-windows (sorted-frames) - "Save information about dedicated windows on frames in SORTED-FRAMES. -Write this to current buffer." - (dolist (frame sorted-frames) - (dolist (win (window-list frame)) - (when (window-dedicated-p win) - (let ((frame-num (length (memq frame sorted-frames))) - (win-num (length - (memq win - (window-list frame t (frame-first-window frame))))) - (flag (window-dedicated-p win))) - (insert (format "(winsav-restore-dedicated-window %s %s %S)\n" frame-num win-num flag)) - ))))) - -(defun winsav-restore-ecb (frame-num layout-ecb) - "Restore ECB. -On frame number FRAME-NUM-ECB in `winsav-loaded-frames' restore -ECB layout LAYOUT-ECB." - (when (boundp 'ecb-minor-mode) - (let* ((frame (nth (1- frame-num) winsav-loaded-frames))) - (select-frame frame) - (unless (string= layout-ecb ecb-layout-name) - (setq ecb-layout-name layout-ecb)) - (ecb-minor-mode 1)))) - -(defun winsav-save-ecb (frame-ecb layout-ecb sorted-frames) - "Save information about ECB layout on frames in SORTED-FRAMES. -Write this in current buffer." - (dolist (frame sorted-frames) - (when (eq frame frame-ecb) - (let ((frame-num (length (memq frame sorted-frames)))) - (insert (format "(winsav-restore-ecb %s %S)\n" frame-num layout-ecb)))))) - -;; (make-frame '((minibuffer))) -;; (sort (frame-list) 'winsav-frame-sort-predicate) -(defun winsav-frame-sort-predicate (a b) - "Compare frame A and B for sorting. -Sort in the order frames can be created. - -- Frames without minibuffers will come later since the need to - refer to the minibuffer frame when they are created. - -- Invisible frames comes last since there must be at least one - visible frame from the beginning." - (let* ((a-mbw (minibuffer-window a)) - (a-mbw-frm (window-frame a-mbw)) - (b-mbw (minibuffer-window b)) - (b-mbw-frm (window-frame b-mbw)) - (a-visible (frame-visible-really-p a)) - (b-visible (frame-visible-really-p b)) - ) - ;;(message "a-mbw-frm=%s, b=%s" a-mbw-frm b) - ;;(message "b-mbw-frm=%s, a=%s" a-mbw-frm b) - (when (or (not b-visible) - (eq a-mbw-frm b) - (not (eq b-mbw-frm b))) - ;;(message "a > b") - t - ))) - -(defun winsav-can-read-config (config-version) - "Return t we can read config file version CONFIG-VERSION." - (when (<= config-version 1) - t)) - -(defvar winsav-file-modtime nil) - -;; Like desktop-save, fix-me -(defun winsav-save-configuration (&optional dirname release) - "Write elisp code to recreate all frames. -Write into the file name computed by `winsav-full-file-name' -given the argument DIRNAME. - -The information that is saved for each frame is its size and -position, the window configuration including buffers and the -parameters in `winsav-frame-parameters-to-save'. If you want save -more information for frames you can do that in the hook -`winsav-after-save-frame-hook'. - -See also the hook variables -`winsav-before-save-configuration-hook' and -`winsav-after-save-configuration-hook'. - -Fix-me: RELEASE is not implemented." - (winsav-save-config-to-file (winsav-full-file-name dirname))) - -(defun winsav-save-config-to-file (conf-file) - "Write elisp code to recreate all frames to CONF-FILE." - (let (start - end - (sorted-frames (sort (frame-list) 'winsav-frame-sort-predicate)) - (frm-nr 0) - frame-ecb - layout-ecb) - ;; Recreating invisible frames hits Emacs bug 3859 - (setq sorted-frames - (delq nil - (mapcar (lambda (f) - (when (frame-parameter f 'visibility) f)) - sorted-frames))) - (when (and (boundp 'ecb-minor-mode) ecb-minor-mode) - (when (frame-live-p ecb-frame) - (setq layout-ecb ecb-layout-name) - (setq frame-ecb ecb-frame)) - (ecb-minor-mode -1) - (sit-for 0) ;; Fix-me: is this needed? - ) - (message "winsav-save-config:here a") - (with-temp-buffer - (let ((this-buffer (current-buffer))) - (message "winsav-save-config:here b") - ;;(erase-buffer) - (insert - ";; -*- mode: emacs-lisp; coding: utf-8; -*-\n" - ";; --------------------------------------------------------------------------\n" - ";; Winsav File for Emacs\n" - ";; --------------------------------------------------------------------------\n" - ";; Created " (current-time-string) "\n" - ";; Winsav file format version " winsav-file-version "\n" - ";; Emacs version " emacs-version "\n\n" - "(if (not (winsav-can-read-config " winsav-file-version "))\n\n" - " (message \"Winsav: Can't read config file with version " winsav-file-version "\")\n") - (message "winsav-save-config:here c") - (insert ";; ---- indirect buffers ------------------------\n") - (winsav-save-indirect-buffers this-buffer) - (message "winsav-save-config:here c.1") - ;;(insert ";; ---- special minibuffers ------------------------\n") - (winsav-save-minibuffers sorted-frames this-buffer) - (message "winsav-save-config:here c.2") - (insert "(setq winsav-loaded-frames nil)\n") - (insert ";; ---- before winsav-before-save-configuration-hook ------------------------\n") - (run-hooks 'winsav-before-save-configuration-hook) - (message "winsav-save-config:here c.2a cb=%s" (current-buffer)) - (insert ";; ---- after winsav-before-save-configuration-hook ------------------------\n\n") - (dolist (frm sorted-frames) - (let ((mb-frm-nr (cadr (assoc frm-nr winsav-minibuffer-alist))) - ;;(mb-frm (when mb-frm-nr (nth mb-frm-nr sorted-frames))) - ) - (message "winsav-save-config:here c.2b.1 tb=%s cb=%s frm=%s" this-buffer (current-buffer) frm) - (winsav-save-frame frm mb-frm-nr this-buffer) - (message "winsav-save-config:here c.2b.2") - (setq frm-nr (1+ frm-nr)))) - (message "winsav-save-config:here c.2c cb=%s" (current-buffer)) - (insert ";; ---- dedicated windows ------------------------\n") - (winsav-save-dedicated-windows sorted-frames) - (message "winsav-save-config:here c.3") - (insert ";; ---- ECB --------------------------------------\n") - (winsav-save-ecb frame-ecb layout-ecb sorted-frames) - (message "winsav-save-config:here c.4") - (insert "\n\n;; ---- before winsav-after-save-configuration-hook ------------------------\n") - (run-hooks 'winsav-after-save-configuration-hook) - (message "winsav-save-config:here c.5") - (insert "\n\n;; ---- before winsav-after-save-configuration-hook ------------------------\n") - (run-hooks 'winsav-after-save-configuration-hook) - (message "winsav-save-config:here c.6") - (insert ";; ---- after winsav-after-save-configuration-hook ------------------------\n") - (insert "\n)\n") - (message "winsav-save-config:here d") - ;; For pp-buffer: - (let (emacs-lisp-mode-hook - after-change-major-mode-hook - change-major-mode-hook) - (font-lock-mode -1) - (emacs-lisp-mode)) - (message "winsav-save-config:here e") - (pp-buffer) - (message "winsav-save-config:here f") - (indent-region (point-min) (point-max)) - (message "winsav-save-config:here g") - ;;(save-buffer 0) ;; No backups - ;;(kill-buffer) - - ;;(with-current-buffer (find-file-noselect file) - (let ((coding-system-for-write 'utf-8)) - (write-region (point-min) (point-max) conf-file nil 'nomessage)) - (setq winsav-file-modtime (nth 5 (file-attributes conf-file))) - (setq winsav-dirname (file-name-as-directory (file-name-directory conf-file))) - (message "winsav-save-config:here h") - )))) - -(defvar winsav-current-config-name nil) - -;;(winsav-restore-configuration) -;;(winsav-full-file-name "~") -;; (defun winsav-restore-winsav-configuration () -;; ) - -(defcustom winsav-after-restore-hook nil - "Normal hook run after a successful `winsav-restore-configuration'." - :type 'hook - :group 'winsav) - -;; Like desktop-read, fix-me -(defun winsav-restore-configuration (&optional dirname) - "Restore frames from default file in directory DIRNAME. -The default file is given by `winsav-default-file-name'. - -The file was probably written by `winsav-save-configuration'. -Delete the frames that were used before." - ;;(message "winsav-restore-configuration %s" dirname) - (winsav-restore-config-from-file (winsav-full-file-name dirname))) - -(defun winsav-restore-config-from-file (conf-file) - "Restore frames from configuration file CONF-FILE. -The file was probably written by `winsav-save-configuration'. -Delete the frames that were used before." - (let ((old-frames (sort (frame-list) 'winsav-frame-sort-predicate)) - (num-old-deleted 0) - ;; Avoid winsav saving during restore. - (winsav-save nil)) - ;;(message "winsav:conf-file=%s" conf-file) - (if (or (not conf-file) - (not (file-exists-p conf-file))) - (progn - (message (propertize "Winsav: No default configuration file found" - 'face 'secondary-selection)) - t) ;; Ok - (setq debug-on-error t) ;; fix-me - (if (file-exists-p conf-file) - (progn - (load conf-file nil nil t) - (setq winsav-file-modtime (nth 5 (file-attributes conf-file))) - (setq winsav-dirname (file-name-as-directory (file-name-directory conf-file))) - (when (< 0 (length winsav-loaded-frames)) - (dolist (old (reverse old-frames)) - (unless (eq 'only (frame-parameter old 'minibuffer)) - (setq num-old-deleted (1+ num-old-deleted)) - (delete-frame old))) - ) - (message "winsav-after-restore-hook =%S" winsav-after-restore-hook) - (run-hooks 'winsav-after-restore-hook) - (message "Winsav: %s frame(s) restored" (length winsav-loaded-frames)) - t) - ;; No winsav file found - ;;(winsav-clear) - (message "No winsav file: %s" conf-file) - nil)))) - -;; (defcustom winsav-add-to-desktop nil -;; "Set this to let desktop save and restore also winsav configurations." -;; :type 'boolean -;; :set (lambda (sym val) -;; (set-default sym val) -;; (if value -;; (progn -;; (add-hook 'desktop-after-read-hook 'winsav-restore-configuration) -;; (add-hook 'desktop-save-hook 'winsav-save-configuration)) -;; (remove-hook 'desktop-after-read-hook 'winsav-restore-configuration) -;; (remove-hook 'desktop-save-hook 'winsav-save-configuration)) ) -;; :group 'winsav) - -(defun winsav-restore-configuration-protected (&optional dirname) - "Like `winsav-restore-configuration' but protect for errors. -DIRNAME has the same meaning." - (condition-case err - (winsav-restore-configuration dirname) - (error - (message "winsav-restore-configuration: %s" err)))) - -(defun winsav-relative-~-or-full (dirname) - (let* ((rel-dir (file-relative-name dirname - (file-name-directory - (winsav-full-file-name "~")))) - (confname (if (string= ".." (substring rel-dir 0 2)) - winsav-dirname - (if (string= rel-dir "./") - "(default)" - (concat "~/" rel-dir))))) - confname)) - -(defun winsav-tell-configuration () - "Tell which winsav configuration that is used." - (interactive) - (save-match-data ;; runs in timer - (let ((confname (if (not winsav-dirname) - "(none)" - (winsav-relative-~-or-full winsav-dirname)))) - (if t ;;(called-interactively-p) - (message (propertize (format "Current winsav config is '%s'" confname) - 'face 'secondary-selection)) - (save-window-excursion - (delete-other-windows) - (set-window-buffer (selected-window) - (get-buffer-create " *winsav*")) - (with-current-buffer (window-buffer) - (momentary-string-display - (propertize - (format "\n\n\n Current winsav config is '%s'\n\n\n\n" confname) - 'face 'secondary-selection) - (window-start) - (kill-buffer)))))))) - -(defun winsav-tell-configuration-request () - "Start an idle timer to call `winsav-tell-configuration'." - (run-with-idle-timer 1 nil 'winsav-tell-configuration)) - - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Startup and shut down - -;; Run after desktop at startup so that desktop has loaded files and -;; buffers. -(defun winsav-after-init () - "Restore frames and windows. -Run this once after Emacs startup, after desktop in the -`after-init-hook'." - ;; Turn off with --no-deskttop: - (unless desktop-save-mode (winsav-save-mode -1)) - (when winsav-save-mode - ;;(run-with-idle-timer 0.1 nil 'winsav-restore-configuration-protected) - ;;(message "winsav-after-init") - ;;(winsav-restore-configuration-protected) - ;; In case of error make sure winsav-save-mode is turned off - (setq inhibit-startup-screen t) - (winsav-save-mode -1) - (winsav-restore-configuration) - (winsav-save-mode 1) - )) - -(add-hook 'after-init-hook 'winsav-after-init t) - -(add-hook 'kill-emacs-hook 'winsav-kill) -;;(remove-hook 'kill-emacs-hook 'winsav-kill) - -(defun winsav-kill () - "Save winsav frame configuration. -Run this before Emacs exits." - ;; (when winsav-save-mode - ;; (let ((conf-dir (when winsav-current-config-name - ;; (winsav-full-config-dir-name winsav-current-config-name)))) - ;; (winsav-save-configuration conf-dir)))) - (when (and winsav-save-mode - (let ((exists (file-exists-p (winsav-full-file-name)))) - (or (eq winsav-save t) - (and exists (memq winsav-save '(ask-if-new if-exists))) - (and - (or (memq winsav-save '(ask ask-if-new)) - (and exists (eq winsav-save 'ask-if-exists))) - (y-or-n-p "Save winsav? "))))) - (unless winsav-dirname - ;; Fix-me: Since this can be a new user of winsav I think the - ;; best thing to do here is to encourage the user to save in the - ;; default directory since otherwise the winsav file will not be - ;; loaded at startup. Desktop does not currently do that however - ;; (report that!). - (when (y-or-n-p "Winsav was not loaded from file. Save it to file? ") - (let* ((full-file (winsav-full-file-name)) - (default-directory (directory-file-name - (file-name-directory full-file)))) - (setq winsav-dirname - (file-name-as-directory - (expand-file-name - (read-directory-name "Directory for winsav file: " nil nil t))))))) - (when winsav-dirname - (condition-case err - ;;(winsav-save winsav-dirname t) - (winsav-save-configuration winsav-dirname) - (file-error - (unless (yes-or-no-p - (format "Error while saving winsav config: %s Save anyway? " - (error-message-string err))) - (signal (car err) (cdr err))))))) - ;; If we own it, we don't anymore. - ;;(when (eq (emacs-pid) (winsav-owner)) (winsav-release-lock)) - ) - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Switching configurations - -(defun winsav-restore-full-config (dirname) - "Restore the winsav configuration in directory DIRNAME. -If NAME is nil then restore the startup configuration." - ;;(desktop-change-dir dirname) - (when (and winsav-handle-also-desktop desktop-save-mode) - (when (eq (emacs-pid) (desktop-owner)) (desktop-release-lock)) - (desktop-clear) - (desktop-read dirname)) - (winsav-restore-configuration dirname) - ;;(setq winsav-current-config-name name) - (winsav-tell-configuration-request)) - -(defun winsav-full-config-dir-name (name) - "Return full directory path where configuration NAME is stored." - (let* ((base-dir (concat (winsav-full-file-name) ".d")) - (conf-dir (expand-file-name name base-dir))) - (setq conf-dir (file-name-as-directory conf-dir)) - ;;(message "conf-dir=%s" conf-dir) - conf-dir)) - -;;;###autoload -(defun winsav-save-full-config (dirname) - "Saved current winsav configuration in directory DIRNAME. -Then change to this configuration. - -See also `winsav-switch-config'." - (unless (file-name-absolute-p dirname) - (error "Directory ame must be absolute: %s" dirname)) - (let* ((conf-dir (or dirname "~")) - (old-conf-dir winsav-dirname)) - (make-directory conf-dir t) - (winsav-save-configuration conf-dir) - (when (and winsav-handle-also-desktop desktop-save-mode) - (desktop-release-lock) - (desktop-save conf-dir)) - ;;(unless (string= winsav-current-config-name name) - (unless (string= old-conf-dir conf-dir) - ;;(setq winsav-current-config-name name) - (winsav-tell-configuration-request)))) - -;; Fix-me: remove named configurations, use just dir as desktop -(defun winsav-switch-to-default-config () - "Change to default winsav configuration. -See also `winsav-switch-config'." - (interactive) - (winsav-switch-config "~")) - -;;;###autoload -(defun winsav-switch-config (dirname) - "Change to winsav configuration in directory DIRNAME. -If DIRNAME is the current winsav configuration directory then -offer to save it or restore it from saved values. - -Otherwise, before switching offer to save the current winsav -configuration. Then finally switch to the new winsav -configuration, creating it if it does not exist. - -If option `desktop-save-mode' is on then buffers and files are also -restored and saved the same way. - -See also option `winsav-save-mode' and command -`winsav-tell-configuration'." - (interactive - (list - (let ((default-directory (or winsav-dirname default-directory)) - (base-dir (concat (winsav-full-file-name) ".d")) - new-dir) - (make-directory base-dir t) - (setq new-dir - (read-directory-name "Winsav: Switch config directory: ")) - (when (string= "" new-dir) (setq new-dir nil)) - (or new-dir - "~")))) - (setq dirname (file-name-as-directory (expand-file-name dirname))) - (catch 'stop - (let ((conf-file (expand-file-name winsav-base-file-name dirname)) - config-exists) - (if (file-exists-p conf-file) - (setq config-exists t) - (unless (y-or-n-p (format "%s was not found. Create it? " conf-file)) - (throw 'stop nil))) - (if (string= winsav-dirname dirname) - (if (y-or-n-p "You are already using this configuration, restore it from saved values? ") - (winsav-restore-full-config winsav-dirname) - (when (y-or-n-p "You are already using this winsav configuration, save it? ") - (winsav-save-full-config winsav-dirname))) - (when (y-or-n-p - (format "Save current config, %s,\n first before switching to %s? " - (if (and winsav-dirname - (not (string= winsav-dirname - (file-name-directory (winsav-full-file-name "~"))))) - winsav-dirname - "the startup config") - dirname)) - (winsav-save-full-config winsav-dirname)) - (if config-exists - (winsav-restore-full-config dirname) - (winsav-save-full-config dirname)))))) - - - - -;;; Old things - -;; (defun winsav-log-buffer () -;; (get-buffer-create "winsav log buffer")) - -;; (defun winsav-log (mark obj) -;; (with-current-buffer (winsav-log-buffer) -;; (insert "=== " mark "===\n" (pp-to-string obj)))) - -;; (global-set-key [f2] 'winsav-test-get) -;; (global-set-key [f3] 'winsav-test-put) -;; (defvar winsav-saved-window-tree nil) - -;; (defun winsav-test-get() -;; (interactive) -;; (setq winsav-saved-window-tree (winsav-get-window-tree))) - -;; (defun winsav-test-put() -;; (interactive) -;; (let ((ret (winsav-put-window-tree winsav-saved-window-tree -;; (selected-window)))) -;; ;;(message "ret=%s" ret) -;; )) - -;; (defun winsav-serialize-to-file (obj file) -;; (with-current-buffer (find-file-noselect file) -;; ;;(erase-buffer) -;; (save-restriction -;; (widen) -;; (goto-char (point-max)) -;; (insert (winsav-serialize obj) -;; "\n")) -;; ;;(basic-save-buffer) -;; )) - -;;(global-set-key [f11] 'winsav-rotate) - -;; (defun winsav-de-serialize-window-tree-from-file (file) -;; (with-current-buffer (find-file-noselect file) -;; (save-restriction -;; (widen) -;; (let ((start (point)) -;; (end nil)) -;; (forward-list) -;; (setq end (point)) -;; ;;(goto-char (point-min)) -;; (winsav-de-serialize-window-tree (buffer-substring-no-properties start end)))))) - -;; (defun winsav-restore-from-file (file) -;; (winsav-put-window-tree -;; (winsav-de-serialize-window-tree-from-file file) -;; (selected-window))) - -;; (defun winsav-de-serialize-window-tree (str) -;; (save-match-data -;; (let ((read-str -;; (replace-regexp-in-string (rx "#"))) -;; ">") -;; "buffer" -;; str)) -;; obj-last -;; obj -;; last) -;; (setq read-str -;; (replace-regexp-in-string (rx "#"))) -;; ">") -;; "nil" -;; read-str)) -;; (setq obj-last (read-from-string read-str)) -;; (setq obj (car obj-last)) -;; (setq last (cdr obj-last)) -;; ;; Fix me, maby check there are only spaces left (or trim them above...) -;; obj))) - -(provide 'winsav) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; winsav.el ends here -- cgit v1.2.3-54-g00ecf