mirror of
https://github.com/doomemacs/doomemacs.git
synced 2025-12-06 10:31:23 -08:00
feat(workspaces): implement tab-local parameters
This commit is contained in:
parent
96a1b72dda
commit
a88cb71a11
3 changed files with 73 additions and 31 deletions
|
|
@ -122,11 +122,8 @@ PLIST can have the following properties:
|
|||
(add-hook 'doom-switch-buffer-hook #'+doom-dashboard-reload-maybe-h)
|
||||
(add-hook 'delete-frame-functions #'+doom-dashboard-reload-frame-h)
|
||||
;; Update `default-directory' in dashboard when switching workspaces
|
||||
(add-hook 'tab-bar-tab-post-select-functions #'+doom-dashboard--tab-detect-project-fn)
|
||||
;; HACK Fix #2219 where, in GUI daemon frames, the dashboard loses center
|
||||
;; alignment after switching (or killing) workspaces.
|
||||
(when (daemonp)
|
||||
(add-hook 'tab-bar-tab-post-select-functions #'+doom-dashboard-reload-maybe-h))))
|
||||
;; (add-hook 'tab-bar-tab-pre-select-functions #'+doom-dashboard--record-project-h)
|
||||
(add-hook 'tab-bar-tab-post-select-functions #'+doom-dashboard--record-project-h)))
|
||||
|
||||
(add-hook 'doom-init-ui-hook #'+doom-dashboard-init-h 'append)
|
||||
|
||||
|
|
@ -288,38 +285,19 @@ whose dimensions may not be fully initialized by the time this is run."
|
|||
(car +doom-dashboard-banner-padding))
|
||||
?\n))))))))
|
||||
|
||||
(defun +doom-dashboard--tab-detect-project-fn (from-tab to-tab &rest _)
|
||||
(defun +doom-dashboard--record-project-h (from-tab to-tab &rest _)
|
||||
"Set dashboard's PWD to current persp's `last-project-root', if it exists.
|
||||
|
||||
This and `+doom-dashboard--tab-record-project-h' provides `persp-mode'
|
||||
This and `+doom-dashboard--persp-record-project-h' provides `persp-mode'
|
||||
integration with the Doom dashboard. It ensures that the dashboard is always in
|
||||
the correct project (which may be different across perspective)."
|
||||
(when (bound-and-true-p tabspaces-mode)
|
||||
(setf (alist-get 'last-project-root from-tab)
|
||||
(doom-project-root))
|
||||
(when-let* ((pwd (alist-get 'last-project-root to-tab)))
|
||||
(ignore-errors
|
||||
(+workspaces-parameter-set (+workspaces-get-by-id (alist-get 'id from-tab))
|
||||
'last-project-root (doom-project-root)))
|
||||
(when-let* ((pwd (+workspaces-parameter to-tab 'last-project-root)))
|
||||
(+doom-dashboard-update-pwd-h pwd))))
|
||||
|
||||
;; (defun +doom-dashboard--persp-detect-project-h (&rest _)
|
||||
;; "Set dashboard's PWD to current persp's `last-project-root', if it exists.
|
||||
|
||||
;; This and `+doom-dashboard--persp-record-project-h' provides `persp-mode'
|
||||
;; integration with the Doom dashboard. It ensures that the dashboard is always in
|
||||
;; the correct project (which may be different across perspective)."
|
||||
;; (when (bound-and-true-p persp-mode)
|
||||
;; (when-let (pwd (persp-parameter 'last-project-root))
|
||||
;; (+doom-dashboard-update-pwd-h pwd))))
|
||||
|
||||
;; (defun +doom-dashboard--persp-record-project-h (&optional persp &rest _)
|
||||
;; "Record the last `doom-project-root' for the current persp.
|
||||
;; See `+doom-dashboard--persp-detect-project-h' for more information."
|
||||
;; (when (bound-and-true-p persp-mode)
|
||||
;; (set-persp-parameter
|
||||
;; 'last-project-root (doom-project-root)
|
||||
;; (if (persp-p persp)
|
||||
;; persp
|
||||
;; (get-current-persp)))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Library
|
||||
|
|
|
|||
|
|
@ -87,6 +87,15 @@ index. If NOERROR? is omitted, throws an error if NAME doesn't exist."
|
|||
(unless noerror?
|
||||
(user-error "No workspace found: %s" name))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspaces-get-by-id (id)
|
||||
"Return the tab by unique ID."
|
||||
(catch 'result
|
||||
(dolist (fr (frame-list))
|
||||
(dolist (tab (tab-bar-tabs fr))
|
||||
(when (equal id (alist-get 'id tab))
|
||||
(throw 'result tab))))))
|
||||
|
||||
;;;###autoload
|
||||
(defalias '+workspaces-exists-p #'tab-bar--tab-index-by-name)
|
||||
|
||||
|
|
@ -139,6 +148,43 @@ workspace."
|
|||
(tabspaces-remove-buffer buffer))
|
||||
(tabspaces-remove-buffer buffer)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspaces-parameter (workspace param &optional default)
|
||||
"Return a WORKSPACE's PARAM, otherwise DEFAULT."
|
||||
(if-let* ((table (gethash (alist-get 'id (or workspace (+workspaces-current)))
|
||||
+workspaces--parameters)))
|
||||
(gethash param table default)
|
||||
default))
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspaces-parameter-set (workspace param val)
|
||||
"Set a WORKSPACE's PARAM to VAL"
|
||||
(let* ((workspace (or workspace (+workspaces-current)))
|
||||
(id (or (alist-get 'id workspace)
|
||||
(error "Workspace has no id attribute: %S" workspace))))
|
||||
(puthash param val (or (gethash id +workspaces--parameters)
|
||||
(error "Invalid workspace ID: %s" id)))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Hooks
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspaces-init-parameters-h (tab)
|
||||
"Initialize the current workspace's parameters."
|
||||
(puthash (alist-get 'id tab) (make-hash-table :test 'eq)
|
||||
+workspaces--parameters))
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspaces-cleanup-parameters-h (_tab _last-tab?)
|
||||
"Cleanup workspace parameters for forgotten workspaces."
|
||||
(dolist (id (hash-table-keys +workspaces--parameters))
|
||||
(or (cl-loop for tab in tab-bar-closed-tabs
|
||||
for tid = (map-nested-elt tab '(tab id))
|
||||
unless (eq (gethash tid +workspaces--parameters t) t)
|
||||
return t)
|
||||
(remhash id +workspaces--parameters))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Interactive commands
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
(defvar +workspaces-dir (file-name-concat doom-profile-data-dir "workspaces/")
|
||||
"The directory where workspace session files are stored.")
|
||||
|
||||
(defvar +workspaces--parameters (make-hash-table :test 'equal))
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
|
@ -37,10 +39,26 @@
|
|||
[remap delete-window] #'+workspaces/close-window-or-workspace
|
||||
[remap evil-window-delete] #'+workspaces/close-window-or-workspace)
|
||||
|
||||
|
||||
;; Per-workspace `winner-mode' history
|
||||
(add-to-list 'window-persistent-parameters '(winner-ring . t))
|
||||
|
||||
|
||||
;; HACK: Emacs tabs don't offer an easy way to associate data with a tab,
|
||||
;; since tab names aren't unique, so these advice is dedicated to providing
|
||||
;; that:
|
||||
(autoload 'uuidgen-1 "uuidgen")
|
||||
(defadvice! +workspaces--embed-id-a (tab)
|
||||
:filter-return #'tab-bar--tab
|
||||
:filter-return #'tab-bar--current-tab-make
|
||||
(unless (alist-get 'id tab)
|
||||
(setq tab (append tab `((id . ,(uuidgen-1))))))
|
||||
tab)
|
||||
(add-to-list 'window-persistent-parameters '(id . writable))
|
||||
|
||||
(add-hook 'tab-bar-tab-post-open-functions #'+workspaces-init-parameters-h)
|
||||
(add-hook 'tab-bar-tab-pre-close-functions #'+workspaces-cleanup-parameters-h)
|
||||
|
||||
|
||||
;; HACK: Tabspaces is hardcoded to equate the root of a version controlled
|
||||
;; project as the only kind of project root, and lacks integration with
|
||||
;; project.el or projectile. This fixes that.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue