-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Non-nil uniquify-buffer-name-style breaks persp switching #104
Comments
hlissner
added a commit
to doomemacs/doomemacs
that referenced
this issue
Jun 26, 2019
- Fixes #1506: unsets uniquify-buffer-name-style to work around breakage in persp-mode having to do with buffers being retrospectively renamed. See Bad-ptr/persp-mode.el#104. - Move creation of main workspace into persp-mode-hook, to ensure main workspace always exists and nil workspace is never active. - Remove +workspaces|init-frame and significantly reduce LOC in +workspaces|init to the bare essentials. This _may_ break persp-mode in daemon Emacs, but I'll deal with that next.
uelei
pushed a commit
to uelei/doom-emacs
that referenced
this issue
Aug 9, 2019
- Fixes doomemacs#1506: unsets uniquify-buffer-name-style to work around breakage in persp-mode having to do with buffers being retrospectively renamed. See Bad-ptr/persp-mode.el#104. - Move creation of main workspace into persp-mode-hook, to ensure main workspace always exists and nil workspace is never active. - Remove +workspaces|init-frame and significantly reduce LOC in +workspaces|init to the bare essentials. This _may_ break persp-mode in daemon Emacs, but I'll deal with that next.
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? |
did this ever happen? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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:
The text was updated successfully, but these errors were encountered: