Files
@ 9524c6280b66
Branch filter:
Location: workgroups2/src/workgroups-wconfig.el
9524c6280b66
9.9 KiB
text/x-elisp
Possible errors with next/prev buffers
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 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | ;;; workgroups-wconfig.el --- WCONFIG
;;; Commentary:
;; This is a window-configuration, a buffer layout, whatever you call
;; it... This is actually what you want to be saved and restored.
;; (Well, technically it is (window-tree + some frame parameters))
;;; Code:
(require 'workgroups-wtree)
(defun wg-frame-to-wconfig (&optional frame)
"Return the serialization (a wg-wconfig) of Emacs frame FRAME.
FRAME nil defaults to `selected-frame'."
(let* ((frame (or frame (selected-frame)))
(fullscrn (frame-parameter frame 'fullscreen)))
(wg-make-wconfig
:left (frame-parameter frame 'left)
:top (frame-parameter frame 'top)
:width (frame-parameter frame 'width)
:height (frame-parameter frame 'height)
:parameters `((fullscreen . ,fullscrn))
:vertical-scroll-bars (frame-parameter frame 'vertical-scroll-bars)
:scroll-bar-width (frame-parameter frame 'scroll-bar-width)
:wtree (wg-window-tree-to-wtree (window-tree frame))
)))
(defun wg-current-wconfig ()
"Return the current wconfig.
If `wg-current-wconfig' is non-nil, return it. Otherwise return
`wg-frame-to-wconfig'."
(or (frame-parameter nil 'wg-current-wconfig)
(wg-frame-to-wconfig)))
(defmacro wg-with-current-wconfig (frame wconfig &rest body)
"Eval BODY with WCONFIG current in FRAME.
FRAME nil defaults to `selected-frame'."
(declare (indent 2))
(wg-with-gensyms (frame-sym old-value)
`(let* ((,frame-sym (or ,frame (selected-frame)))
(,old-value (frame-parameter ,frame-sym 'wg-current-wconfig)))
(unwind-protect
(progn
(set-frame-parameter ,frame-sym 'wg-current-wconfig ,wconfig)
,@body)
(when (frame-live-p ,frame-sym)
(set-frame-parameter ,frame-sym 'wg-current-wconfig ,old-value))))))
(defun wg-make-blank-wconfig (&optional buffer)
"Return a new blank wconfig.
BUFFER or `wg-default-buffer' is visible in the only window."
(save-window-excursion
(delete-other-windows)
(switch-to-buffer (or buffer wg-default-buffer))
(wg-frame-to-wconfig)))
(defun wg-wconfig-move-window (wconfig offset)
"Offset `selected-window' OFFSET places in WCONFIG."
(wg-asetf (wg-wconfig-wtree wconfig) (wg-wtree-move-window it offset))
wconfig)
;;; base wconfig updating
(defun wg-update-working-wconfig-on-delete-frame (frame)
"Update FRAME's current workgroup's working-wconfig before
FRAME is deleted, so we don't lose its state."
(with-selected-frame frame
(wg-update-current-workgroup-working-wconfig)))
(defun wg-wconfig-buf-uids (wconfig)
"Return WCONFIG's wtree's `wg-wtree-buf-uids'."
(if (not (wg-wconfig-wtree wconfig))
(error "WTREE is nil in `wg-wconfig-buf-uids'!"))
(wg-wtree-unique-buf-uids (wg-wconfig-wtree wconfig)))
(defun wg-wconfig-restore-frame-position (wconfig &optional frame)
"Use WCONFIG to restore FRAME's position.
If frame is nil then `selected-frame'."
(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 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-wconfigs-wtree (wconfig new-width new-height)
"Scale WCONFIG's wtree with NEW-WIDTH and NEW-HEIGHT.
Return a copy WCONFIG's wtree scaled with `wg-scale-wtree' by the
ratio or NEW-WIDTH to WCONFIG's width, and NEW-HEIGHT to
WCONFIG's height."
(wg-normalize-wtree
(wg-scale-wtree
(wg-wconfig-wtree wconfig)
(/ (float new-width) (wg-wconfig-width wconfig))
(/ (float new-height) (wg-wconfig-height wconfig)))))
;; (wg-wconfig-width (wg-current-wconfig))
;; (wg-wconfig-wtree (wg-current-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)))
;; (wg-scale-wconfig-to-frame (wg-current-wconfig))
(defun wg-frame-resize-and-position (wconfig &optional frame)
"Apply WCONFIG's size and position to a FRAME."
(interactive)
(unless frame
(setq frame (selected-frame)))
(let* ((params (wg-wconfig-parameters wconfig))
fullscreen)
(set-frame-parameter frame 'fullscreen (if (assoc 'fullscreen params)
(cdr (assoc 'fullscreen params))
nil))
(when (and wg-restore-frame-position
(not (frame-parameter frame 'fullscreen)))
(wg-wconfig-restore-frame-position wconfig frame))
))
(defun wg-restore-frame-size-position (wconfig &optional fs)
"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 fs
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))
))
(defun wg-restore-frames ()
"Try to recreate opened frames, take info from session's 'frame-list parameter."
(interactive)
(delete-other-frames)
(when (wg-current-session t)
(let ((fl (wg-session-parameter (wg-current-session t) 'frame-list nil))
(frame (selected-frame)))
(mapc (lambda (wconfig)
(with-selected-frame (make-frame)
;;(wg-frame-resize-and-position wconfig)
;;(wg-restore-frame-size-position wconfig)
;;(wg-wconfig-restore-frame-position wconfig)
(wg-restore-wconfig wconfig)
)) fl)
(select-frame-set-input-focus frame))))
;; FIXME: throw a specific error if the restoration was unsuccessful
(defun wg-restore-wconfig (wconfig &optional frame)
"Restore a workgroup configuration WCONFIG in a FRAME.
Runs each time you're switching workgroups."
(unless frame (setq frame (selected-frame)))
(let ((wg-record-incorrectly-restored-bufs t)
(wg-incorrectly-restored-bufs nil)
(params (wg-wconfig-parameters wconfig))
fullscreen wtree)
(wg-barf-on-active-minibuffer)
(when wg-restore-scroll-bars
(wg-wconfig-restore-scroll-bars wconfig))
;; Restore buffers
(wg-restore-window-tree
(wg-scale-wconfig-to-frame wconfig))
;; 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 frame))
(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)))))
;;; saved wconfig commands
(defun wg-save-wconfig ()
"Save the current wconfig to the current workgroup's saved wconfigs."
(interactive)
(let* ((workgroup (wg-current-workgroup))
(name (wg-read-saved-wconfig-name workgroup))
(wconfig (wg-current-wconfig)))
(setf (wg-wconfig-name wconfig) name)
(wg-workgroup-save-wconfig workgroup wconfig)
(wg-fontified-message
(:cmd "Saved: ")
(:cur name))))
(defun wg-restore-saved-wconfig ()
"Restore one of the current workgroup's saved wconfigs in `selected-frame'."
(interactive)
(let ((workgroup (wg-current-workgroup)))
(wg-restore-wconfig-undoably
(wg-workgroup-get-saved-wconfig
workgroup
(wg-completing-read
"Saved wconfig: "
(mapcar 'wg-wconfig-name (wg-workgroup-saved-wconfigs workgroup))
nil t)))))
(defun wg-kill-saved-wconfig ()
"Kill one of the current workgroup's saved wconfigs.
Also add it to the wconfig kill-ring."
(interactive)
(let* ((workgroup (wg-current-workgroup))
(wconfig (wg-read-saved-wconfig workgroup)))
(wg-workgroup-kill-saved-wconfig workgroup wconfig)
(wg-add-to-wconfig-kill-ring wconfig)
(wg-fontified-message
(:cmd "Deleted: ")
(:cur (wg-wconfig-name wconfig)))))
(defun wg-reverse-wconfig (wconfig &optional dir)
"Reverse WCONFIG's wtree's wlist in direction DIR."
(wg-asetf (wg-wconfig-wtree wconfig) (wg-reverse-wlist it dir))
wconfig)
(provide 'workgroups-wconfig)
;;; workgroups-wconfig.el ends here
|