Open hlissner opened 5 years ago
Something like:
(with-eval-after-load "persp-mode"
(with-eval-after-load "uniquify"
(defun persp--wc-bufs (wc)
(let (buf-list)
(cl-labels
((collect-wc-bufs (lst)
(cond
((and lst (listp lst))
(let (head)
(while (and (listp lst)
(setq head (pop lst)))
(cond
((listp head)
(collect-wc-bufs head))
(t (cl-case head
((hc vc leaf)
nil)
(buffer
(push lst buf-list)))))))))))
(collect-wc-bufs wc))
buf-list))
(defun persp-around-uniquify-rename-buffer (urb-f item buf-new-name)
(if persp-mode
(let* ((buf (uniquify-item-buffer item))
(buf-old-name (buffer-name buf))
(buf-persps (persp-persps))
(buf-new-name (funcall urb-f item buf-new-name)))
(when (and buf-new-name (not (string= buf-old-name buf-new-name)))
(cl-mapc
#'(lambda (bl)
(when (string= (first bl) buf-old-name)
(setf (first bl) buf-new-name)))
(cl-mapcan
#'persp--wc-bufs
(cl-mapcar #'safe-persp-window-conf buf-persps))))
buf-new-name)
(funcall urb-f item buf-new-name))))
(advice-add #'uniquify-rename-buffer :around #'persp-around-uniquify-rename-buffer))
OR
(with-eval-after-load "persp-mode"
(defun persp--wc-bufs (wc)
(let (buf-list)
(cl-labels
((collect-wc-bufs (lst)
(cond
((and lst (listp lst))
(let (head)
(while (and (listp lst)
(setq head (pop lst)))
(cond
((listp head)
(collect-wc-bufs head))
(t (cl-case head
((hc vc leaf)
nil)
(buffer
(push lst buf-list)))))))))))
(collect-wc-bufs wc))
buf-list))
(defun persp-around-rename-buffer (rb-f &rest args)
(if persp-mode
(let* ((buf (current-buffer))
(buf-old-name (buffer-name buf))
(buf-persps ;; (persp--buffer-in-persps buf)
(persp-persps))
(buf-new-name (apply rb-f args)))
;;(message "AAA: %s %s %s" buf buf-old-name buf-new-name)
(when (and buf-new-name (not (string= buf-old-name buf-new-name)))
(cl-mapc
#'(lambda (bl)
(when (string= (first bl) buf-old-name)
(setf (first bl) buf-new-name)))
(cl-mapcan
#'persp--wc-bufs
(cl-mapcar #'safe-persp-window-conf buf-persps))))
buf-new-name)
(apply rb-f args)))
(advice-add #'rename-buffer :around #'persp-around-rename-buffer))
OR
(with-eval-after-load "persp-mode"
(defun persp--wc-to-writable (wc)
(cl-labels
((wc-to-writable
(it)
(cond
((and it (listp it))
(cl-destructuring-bind (head . tail) it
(cond
;; ((listp head)
;; (cons (wc-to-writable head)
;; (wc-to-writable tail)))
((eq 'parameters head)
(let ((rw-params
(delq nil
(mapcar
#'(lambda (pc)
(when
(and
(alist-get (car pc) window-persistent-parameters)
(persp-elisp-object-readable-p (cdr pc)))
pc))
tail))))
(if rw-params
`(parameters
,@rw-params)
:delete)))
(t
(let ((new-head (wc-to-writable head))
(new-tail (wc-to-writable tail)))
(when (eq :delete new-tail)
(setq new-tail nil))
(if (eq :delete new-head)
new-tail
(cons new-head
new-tail)))))))
((bufferp it)
(if (buffer-live-p it)
(buffer-name it)
"*Messages*"))
((markerp it)
(marker-position it))
(t it))))
(wc-to-writable wc)))
(setq persp-window-state-get-function
#'(lambda (&optional frame rwin)
(when (or rwin (setq rwin (frame-root-window
(or frame (selected-frame)))))
(window-state-get rwin nil))))
(add-hook 'persp-before-save-state-to-file-functions
#'(lambda (_fname phash _rpfp)
(mapc
#'(lambda (persp)
(if persp
(setf (persp-window-conf persp)
(persp--wc-to-writable (persp-window-conf persp)))
(setq persp-nil-wconf
(persp--wc-to-writable persp-nil-wconf))))
(persp-persps phash)))))
updated
@Bad-ptr It seems like the fix you wrote in your comment works. Have you considered adding it to the main repo?
The problem:
If
uniquify-buffer-name-style
is non-nil, then buffers with conflicting names are renamed retroactively. i.e. opening x.el in one directory and x.el in another will cause uniquify to rename them toa/x.el
andb/x.el
. This is a problem if you've opened a/x.el in perspective 1 and b/x.el in perspective 2. Switching between the two perspectives will cause persp-mode to silently fail to load the newly activated perspective's window configuration because, presumably, the buffers were serialized with their old names and now cannot find the aforementioned buffers by their original names.Steps to reproduce:
From vanilla Emacs (
emacs -Q
):Expected result:
a
perspectivea/file
Observed result:
a
perspectiveb/file
(perspectiveb
's window configuration)No messages are printed to *Messages* and no error is produced.
System information: