Files
@ 454aa3e3d784
Branch filter:
Location: workgroups2/src/workgroups-restore.el
454aa3e3d784
9.2 KiB
text/x-elisp
restoring speedbar-mode
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | ;;; workgroups-restore --- Functions to restore buffers and frames
;;; Commentary:
;;
;; TIPS
;;---------
;; Each Emacs frame ("window") can contain several workgroups.
;; WCONFIG is settings for each workgroup (buffers, parameters,...)
;;
;; So restoring WCONFIG using `wg-restore-wconfig' is restoring buffers
;; for current workgroup. Generally speaking each Workgroup can have
;; several WCONFIGs.
;;
;;; Code:
(require 'workgroups-variables)
(defun wg-restore-default-buffer ()
"Switch to `wg-default-buffer'."
(switch-to-buffer wg-default-buffer t))
(defun wg-restore-existing-buffer (buf)
"Switch to and return BUF's referrent (some live buffer) if it exists."
(wg-awhen (wg-find-buf-in-buffer-list buf (buffer-list))
(switch-to-buffer it t)
(wg-set-buffer-uid-or-error (wg-buf-uid buf))
it))
(defun wg-restore-file-buffer (buf)
"Restore BUF by finding its file. Return the created buffer.
If BUF's file doesn't exist, call `wg-restore-default-buffer'"
(wg-when-let ((file-name (wg-buf-file-name buf)))
(when (or wg-restore-remote-buffers
(not (file-remote-p file-name)))
(cond ((file-exists-p file-name)
(find-file file-name)
(rename-buffer (wg-buf-name buf) t)
(wg-set-buffer-uid-or-error (wg-buf-uid buf))
(when wg-restore-mark
(set-mark (wg-buf-mark buf))
(deactivate-mark))
(wg-deserialize-buffer-local-variables buf)
(current-buffer))
(t
;; try directory
(if (not (file-remote-p file-name))
(if (file-directory-p (file-name-directory file-name))
(progn
(dired (file-name-directory file-name))
(current-buffer))
(progn
(message "Attempt to restore nonexistent file: %S" file-name)
nil))
nil)
)))))
(defun wg-restore-special-buffer (buf)
"Restore a buffer BUF with DESERIALIZER-FN."
(wg-when-let
((special-data (wg-buf-special-data buf))
(buffer (save-window-excursion
(condition-case err
(funcall (car special-data) buf)
(error (message "Error deserializing %S: %S"
(wg-buf-name buf) err)
nil)))))
(switch-to-buffer buffer t)
(wg-set-buffer-uid-or-error (wg-buf-uid buf))
buffer))
(defun wg-restore-buffer (buf)
"Restore BUF and return it."
(let (wg-buffer-auto-association-on)
(or (wg-restore-existing-buffer buf)
(wg-restore-special-buffer buf)
(wg-restore-file-buffer buf)
(progn (wg-restore-default-buffer) nil))))
(defun wg-restore-window-positions (win &optional window)
"Restore various positions in WINDOW from their values in WIN."
(let ((window (or window (selected-window))))
(wg-with-slots win
((win-point wg-win-point)
(win-start wg-win-start)
(win-hscroll wg-win-hscroll))
(set-window-start window win-start t)
(set-window-hscroll window win-hscroll)
(set-window-point
window
(cond ((not wg-restore-point) win-start)
((eq win-point :max) (point-max))
(t win-point)))
(when (>= win-start (point-max)) (recenter)))))
(defun wg-restore-window (win)
"Restore WIN in `selected-window'."
(let ((selwin (selected-window))
(buf (wg-find-buf-by-uid (wg-win-buf-uid win))))
(if (not buf) (wg-restore-default-buffer)
(when (wg-restore-buffer buf)
(wg-restore-window-positions win selwin)
(when wg-restore-window-dedicated-p
(set-window-dedicated-p selwin (wg-win-dedicated win)))))))
(defun wg-reset-window-tree ()
"Delete all but one window in `selected-frame', and reset
various parameters of that window in preparation for restoring
a wtree."
(delete-other-windows)
(set-window-dedicated-p nil nil))
(defun wg-restore-window-tree-helper (w)
"Recursion helper for `wg-restore-window-tree'."
(if (wg-wtree-p w)
(loop with dir = (wg-wtree-dir w)
for (win . rest) on (wg-wtree-wlist w)
do (when rest (split-window nil (wg-w-size win dir) (not dir)))
do (wg-restore-window-tree-helper win))
(wg-restore-window w)
(when (wg-win-selected w)
(setq wg-window-tree-selected-window (selected-window)))
(when (wg-win-minibuffer-scroll w)
(setq minibuffer-scroll-window (selected-window)))
(other-window 1)))
(defun wg-restore-window-tree (wtree)
"Restore WTREE in `selected-frame'."
(let ((window-min-width wg-window-min-width)
(window-min-height wg-window-min-height)
(wg-window-tree-selected-window nil))
(wg-reset-window-tree)
(wg-restore-window-tree-helper wtree)
(wg-awhen wg-window-tree-selected-window (select-window it))))
(defun wg-wconfig-restore-frame-position (wconfig)
"Restore `selected-frame's position from WCONFIG."
(wg-when-let ((left (wg-wconfig-left wconfig))
(top (wg-wconfig-top wconfig)))
;; Check that arguments are integers
;; Problem: https://github.com/pashinin/workgroups2/issues/15
(if (and (integerp left)
(integerp top))
(set-frame-position (selected-frame) left top))))
(defun wg-wconfig-restore-scroll-bars (wconfig)
"Restore `selected-frame's scroll-bar settings from WCONFIG."
(set-frame-parameter
nil 'vertical-scroll-bars (wg-wconfig-vertical-scroll-bars wconfig))
(set-frame-parameter
nil 'scroll-bar-width (wg-wconfig-scroll-bar-width wconfig)))
;;(defun wg-wconfig-restore-fullscreen (wconfig)
;; "Restore `selected-frame's fullscreen settings from WCONFIG."
;; (set-frame-parameter
;; nil 'fullscreen (wg-wconfig-parameters wconfig))
;; )
(defun wg-scale-wconfig-to-frame (wconfig)
"Scale WCONFIG buffers to fit current frame size.
Return a scaled copy of WCONFIG."
(interactive)
(wg-scale-wconfigs-wtree wconfig
(frame-parameter nil 'width)
(frame-parameter nil 'height)))
(defun wg-frame-resize-and-position (wconfig)
"Resize and position a frame based on WCONFIG of current workgroup."
(interactive)
(let* ((params (wg-wconfig-parameters wconfig))
fullscreen)
(set-frame-parameter nil 'fullscreen (if (assoc 'fullscreen params)
(cdr (assoc 'fullscreen params))
nil))
(when (and wg-restore-frame-position
(not (frame-parameter nil 'fullscreen)))
(wg-wconfig-restore-frame-position wconfig))
))
(defun wg-restore-frame-size-position (wconfig)
"Smart-restore of frame size and position.
Depending on `wg-remember-frame-for-each-wg' frame parameters may
be restored for each workgroup.
If `wg-remember-frame-for-each-wg' is nil (by default) then
current frame parameters are saved/restored to/from first
workgroup. And frame parameters for all other workgroups are just
ignored.
"
(interactive)
(let* ((params (wg-wconfig-parameters wconfig))
fullscreen)
;; Frame maximized / fullscreen / none
(unless wg-remember-frame-for-each-wg
(setq params (wg-wconfig-parameters (wg-workgroup-working-wconfig (wg-first-workgroup)))))
(setq fullscreen (if (assoc 'fullscreen params)
(cdr (assoc 'fullscreen params))
nil))
(when (and fullscreen
(or wg-remember-frame-for-each-wg
(null (wg-current-workgroup t))))
(set-frame-parameter nil 'fullscreen fullscreen)
;; I had bugs restoring maximized frame:
;; Frame could be maximized but buffers are not scaled to fit it.
;;
;; Maybe because of `set-frame-parameter' takes some time to finish and is async.
;; So I tried this and it helped
(sleep-for 0 100))
;; Position
(when (and wg-restore-frame-position
wg-remember-frame-for-each-wg
(not (frame-parameter nil 'fullscreen)))
(wg-wconfig-restore-frame-position wconfig))
))
;; FIXME: throw a specific error if the restoration was unsuccessful
(defun wg-restore-wconfig (wconfig)
"Restore a workgroup configuration WCONFIG in `selected-frame'.
Runs each time you're switching workgroups."
(let ((wg-record-incorrectly-restored-bufs t)
(wg-incorrectly-restored-bufs nil)
(params (wg-wconfig-parameters wconfig))
fullscreen wtree)
(wg-barf-on-active-minibuffer)
(wg-restore-frame-size-position wconfig)
(when wg-restore-scroll-bars
(wg-wconfig-restore-scroll-bars wconfig))
(setq wtree (wg-scale-wconfig-to-frame wconfig)) ; scale wtree to frame size
;; Restore buffers
(wg-restore-window-tree
(if (not (wg-morph-p)) wtree (wg-morph wtree)))
;; Restore frame position
(when (and wg-restore-frame-position
(not (frame-parameter nil 'fullscreen))
(null (wg-current-workgroup t)))
(wg-wconfig-restore-frame-position wconfig))
(when wg-incorrectly-restored-bufs
(message "Unable to restore these buffers: %S\
If you want, restore them manually and try again."
(mapcar 'wg-buf-name wg-incorrectly-restored-bufs)))))
(provide 'workgroups-restore)
;;; workgroups-restore.el ends here
|