fix(workspaces): clobbering pre-existing workspaces on switch-project

If you used `projectile-switch-project`, the workspaces module would
open a new workspace named after the project, but if a  workspace named
after that project already exists, it is hijacked (e.g. two projects in
'some-project/src' and 'another-project/src' would get the same name:
"src"). This commit uniquifies their names so this doesn't happen, and
also embeds a +workspace-project persp parameter in the workspace so
that they can be disamiguated later (this association is lost if you
rename the workspace manually, however).

Fix: #7637
This commit is contained in:
Henrik Lissner
2025-04-01 03:21:46 -04:00
parent c6f979b4e0
commit 6f6302d42d

View File

@ -564,8 +564,27 @@ This be hooked to `projectile-after-switch-project-hook'."
(or (eq +workspaces-on-switch-project-behavior t)
(+workspace--protected-p (safe-persp-name (get-current-persp)))
(+workspace-buffer-list)))
(let ((persp (or (+workspace-get pname t)
(+workspace-new pname))))
(let* ((ws-param '+workspace-project)
(ws (+workspace-get pname t))
(ws (if (and ws
(ignore-errors
(file-equal-p (persp-parameter ws-param ws)
proot)))
ws
;; Uniquify the project's name, so we don't clobber a
;; pre-existing workspace with the same name.
(let* ((parts (nreverse (split-string proot "/" t)))
(pre (cdr parts))
(post (list (car parts))))
(while (and pre
(setq ws (+workspace-get (setq pname (string-join post "/")) t))
(not (ignore-errors
(file-equal-p (persp-parameter ws-param ws)
proot))))
(push (pop pre) post))
(unless pre ws))))
(ws (or ws (+workspace-new pname))))
(set-persp-parameter ws-param proot ws)
(+workspace-switch pname)
(with-current-buffer (doom-fallback-buffer)
(setq-local default-directory proot)