Skip to content

Commit cae91b2

Browse files
committed
feat(core): add +define-dedicated-workspace!
1 parent a5ce718 commit cae91b2

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

core/me-loaddefs.el

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,14 @@ prefix or universal argument, it waits for a moment (defined by
123123
Return the region or the thing at point.")
124124
(autoload '+webjump "../elisp/+emacs" "\
125125
Like `webjump', with initial query filled from `+region-org-thing-at-point'." t)
126+
(autoload '+define-dedicated-workspace! "../elisp/+emacs" "\
127+
Define +NAME command to run BODY in a dedicated workspace.
128+
If not specified, BODY defaults to `(NAME)'.
129+
130+
You can pass an exit hook or exit function on which, the created workspace will
131+
be deleted.
132+
133+
(fn NAME [[:exit-hook HOOK] [:exit-func FUNC]] FORMS...)" nil t)
126134
(register-definition-prefixes "../elisp/+emacs" '("+dir-locals--autoreload-" "+screenshot-" "+webjump-read-string-"))
127135

128136

elisp/+emacs.el

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,50 @@ prefix or universal argument, it waits for a moment (defined by
137137
(cl-letf (((symbol-function 'webjump-read-string) #'+webjump-read-string-with-initial-query))
138138
(webjump))))
139139

140+
;;;###autoload
141+
(defmacro +define-dedicated-workspace! (name &rest body)
142+
"Define +NAME command to run BODY in a dedicated workspace.
143+
If not specified, BODY defaults to `(NAME)'.
144+
145+
You can pass an exit hook or exit function on which, the created workspace will
146+
be deleted.
147+
148+
\(fn NAME [[:exit-hook HOOK] [:exit-func FUNC]] FORMS...)"
149+
(let* ((name (+unquote name))
150+
(fn-name (intern (format "+%s" name)))
151+
(fn-doc (format "Launch %s in a dedicated workspace." name))
152+
(tab-name (intern (format "+%s-tab-name" name)))
153+
(exit-fn-name (intern (format "+%s--close-workspace" name)))
154+
exit-func exit-hook sexp fn-body)
155+
(while (keywordp (car body))
156+
(pcase (pop body)
157+
(:exit-func (setq exit-func (+unquote (pop body))))
158+
(:exit-hook (setq exit-hook (+unquote (pop body))))))
159+
(setq sexp (if (null body) `((,name)) body))
160+
(when (or exit-func exit-hook)
161+
(setq
162+
fn-body
163+
`((defun ,exit-fn-name ()
164+
(if (fboundp 'tabspaces-mode)
165+
;; When `tabspaces' is available, use it.
166+
(when-let ((tab-num (seq-position (tabspaces--list-tabspaces) ,tab-name #'string=)))
167+
(tabspaces-close-workspace (1+ tab-num)))
168+
;; Or default to the built-in `tab-bar'.
169+
(when-let ((tab-num (seq-position (tab-bar-tabs) ,tab-name (lambda (tab name) (string= name (alist-get 'name tab))))))
170+
(tab-close (1+ tab-num)))))))
171+
(when exit-func (add-to-list 'fn-body `(advice-add ',exit-func :after #',exit-fn-name) t))
172+
(when exit-hook (add-to-list 'fn-body `(add-hook ',exit-hook #',exit-fn-name) t)))
173+
`(progn
174+
(defvar ,tab-name ,(format "*%s*" name))
175+
(defun ,fn-name ()
176+
,fn-doc
177+
(interactive)
178+
(when ,tab-name
179+
(if (fboundp 'tabspaces-mode)
180+
(tabspaces-switch-or-create-workspace ,tab-name)
181+
(tab-new)
182+
(tab-rename +mu4e-tab-name)))
183+
,@sexp)
184+
,(macroexp-progn fn-body))))
185+
140186
;;; +emacs.el ends here

0 commit comments

Comments
 (0)