Open toupeira opened 8 years ago
Well, I don't use the projectile, so can't say for sure.
You code looks mostly correct and it should work. But actually when I was writing the def-auto-persp
macro I didn't think it could be used to dynamically create perspectives with different names.
To adress this I added the :get-name-expr
parameter: 7f21fd8207a3584bf1509d345057ef8658d6bfb9. It is intended to be used like this:
(def-auto-persp "projectile"
:hooks (projectile-mode-hook)
:get-name-expr (projectile-project-root)
:predicate (lambda (buffer)
(and (not (eq nil (buffer-file-name buffer)))
(bound-and-true-p projectile-mode)
(projectile-project-p)
(projectile-project-buffer-p buffer (projectile-project-root))))
:on-match (lambda (perspective buffer after-match hook args)
(persp-frame-switch perspective)))
And it is the more correct way(Especially if in the feature I'll decide to change something). I have not tested it though.)
Thanks, I assumed get-persp-expr
was for that but couldn't get it to work :)
I also switched to find-file-hook
instead of projectile-mode-hook
which seems more reliable, though I still have the problem that previously opened buffers don't trigger that hook, so I end up with a buffer in the "wrong" perspective. Is there perhaps some mechanism in persp-mode to work around this, e.g. by setting a buffer-local variable to trigger a given perspective or something?
though I still have the problem that previously opened buffers don't trigger that hook, so I end up with a buffer in the "wrong" perspective. Is there perhaps some mechanism in persp-mode to work around this, e.g. by setting a buffer-local variable to trigger a given perspective or something?
Ok, I have long wanted to do this.
Breaking changes 5a3f8f92712a5da031cf07674fd4c350e56111e6 (Readme is also updated).
def-auto-persp
is now a defun, so you must quote arguments(except lambdas). Notice that the argument list of the :on-match
callback has changed. Also notice that auto persp definitions is now stored in the persp-auto-persp-alist
variable.
See the persp-auto-persp-pickup-buffer* family of functions.
Hope this will do it for you(I have not tested how well it works).
Hmm I get an error "Don't know how to compile nil" with the latest version, running with --debug-init --eval '(setq debug-on-error t byte-compile-debug t)
gives me
Debugger entered--Lisp error: (error "Don't know how to compile nil")
[..]
byte-compile(nil)
(set-frame-parameter frame (quote buffer-predicate) (byte-compile new-pred))
[..]
persp-set-frame-buffer-predicate(#<frame *spacemacs* [emacs.d] 0x878b140>)
[..]
persp-init-frame(#<frame *spacemacs* [emacs.d] 0x878b140>)
[..]
persp-mode()
[..]
It sounds like it's related to your other commit 191715a73b605ad219b9f430b462767fe727fef3
What version of emacs are you using? Try doing this: M-: (byte-compile nil) RET
For me it outputs:
Function nil is already compiled
#[nil "À" [nil] 1]
emacs --version GNU Emacs 25.1.50.1
(byte-compile nil)
gives me the same error. I'm on the latest stable release 24.5 on Debian unstable:
GNU Emacs 24.5.1 (i586-pc-linux-gnu, GTK+ Version 3.18.9) of 2016-04-08 on x86-csail-01, modified by Debian
Ok latest version compiles again!
Thanks a lot for your changes, I now have the following:
(def-auto-persp "projectile"
:parameters '((dont-save-to-file . t))
:hooks '(after-change-major-mode-hook)
:predicate
(lambda (buffer)
(with-current-buffer buffer
(and
(buffer-file-name)
(projectile-project-p))))
:get-name-expr
(lambda ()
(abbreviate-file-name (projectile-project-root)))
:after-match
(lambda (persp-name persp buffer &rest args)
(persp-frame-switch persp-name)))
I had to add :hooks '(after-change-major-mode-hook)
or I would get an error wrong-type-argument consp nil
on startup, though everything else still seems to work the same.
Also without the :after-match
the new perspective wouldn't be switched to, is that intentional?
There's still an issue though:
persp-buffer-list
, and persp-remove-buffer (current-buffer) (get-current-persp)
doesn't do anything eitherI'm also trying out an advice on find-file
:
(advice-add 'find-file :after 'dotfiles/switch-to-project-layout)
(defun dotfiles/switch-to-project-layout (&rest args)
(when (projectile-project-p)
(let* ((buffer (current-buffer))
(old-persp (get-current-persp))
(new-persp (abbreviate-file-name (projectile-project-root))))
;; make sure the old window is still showing the same buffer
(switch-to-buffer (other-buffer))
;; switch to the new perspective
(persp-switch new-persp)
;; make sure the new buffer is added to the perspective and switched to
(persp-add-buffer buffer)
;; if the perspective changed, make sure the new buffer is gone from the old perspective
(when (and old-persp (not (string= new-persp (persp-name old-persp))))
(persp-remove-buffer buffer old-persp)))))
So far this seems to cover all edge cases I ran into with my previous attempts, while the approach with def-auto-persp
seems to be missing the switch-to-buffer
part.
Also, the advice on find-file
is the first hook I found that reliably triggers in all the cases I need, the problem with after-change-major-mode-hook
is that it doesn't trigger for already opened buffers, and file-find-hook
also triggers on find-file-noselect
which causes all sorts of weird issues (e.g. company-mode
triggers it randomly while typing)
I had to add :hooks '(after-change-major-mode-hook) or I would get an error wrong-type-argument consp nil
Fixed b91ed0682894bbd97a35e11b9a2554abf08a9750.
Also without the :after-match the new perspective wouldn't be switched to, is that intentional?
Added :switch
parameter dfb4e8397e85b241834a65cd797a3d0d9f5d5baf.
now I still see the file from project B in layout A, even though it's not a member of persp-buffer-list
Probably fixed 50c05c56c5b29d9e9bc15416abfc37b87a27151b.
You could try this:
(defvar after-find-file-hook nil)
(defun dotfiles/after-find-file-adv (&rest args)
(run-hooks 'after-find-file-hook))
(advice-add 'find-file :after 'dotfiles/after-find-file-adv)
(def-auto-persp "projectile"
:parameters '((dont-save-to-file . t))
:hooks '(after-find-file-hook)
:switch 'frame
:predicate
#'(lambda (buffer)
(and
(buffer-file-name)
(projectile-project-p)))
:get-name-expr
#'(lambda ()
(abbreviate-file-name (projectile-project-root))))
Thanks, I tried your code without changes, but I still experience this issue:
now I still see the file from project B in layout A, even though it's not a member of persp-buffer-list
Also, if I'm switching to an already opened buffer it doesn't get displayed at all in the new perspective, only in the old one.
Let me know if you want to keep looking into this, otherwise I'm happy to keep my mostly-working advice kludge and stop bothering you ;-)
Let me know if you want to keep looking into this
Yes, I think it can be useful. So I'll install projectile to see what's goes wrong.
I think I made it to work. (However, there is still a problem with emacsclient and server-switch-hook.) d071a4a7b6997d35bc0b559a01e7975b832bc203...dad19945146ad653fbd618ff477dc19e7b650d60
(defvar after-find-file-hook nil)
(defun my/-after-find-file-adv (&rest args)
(run-hooks 'after-find-file-hook))
(advice-add 'find-file :after 'my/-after-find-file-adv)
(def-auto-persp "projectile"
:parameters '((dont-save-to-file . t))
:hooks '(after-find-file-hook)
:switch 'frame
:predicate
#'(lambda (buffer)
(and
(buffer-file-name)
(projectile-project-p)))
:get-name-expr
#'(lambda ()
(abbreviate-file-name (projectile-project-root))))
(setq persp-add-buffer-on-find-file 'if-not-autopersp)
(add-hook 'persp-after-load-state-functions #'(lambda (&rest args) (persp-auto-persps-pickup-buffers)) t)
Now I'm getting an error persp-contain-buffer-p: Wrong type argument: arrayp, t
on startup, also see https://github.com/syl20bnr/spacemacs/issues/6366
But thanks for your changes, looking forward to try it out!
persp-contain-buffer-p: Wrong type argument: arrayp, t
shit). This should fix it f9638fac82a5e6a38b329e5d936c7a0067b2ca5e.
This should fix it f9638fa.
It works. Thanks for the quick fix.
Just had another look with your latest changes, I still had the issue that newly opened buffers were also selected in the old perspective, but after adding the switch-to-buffer
line from my version it seems to work the same now. Here's the full code:
(defvar after-find-file-hook nil)
(defun dotfiles/after-find-file-adv (&rest args) (run-hooks 'after-find-file-hook))
(advice-add 'find-file :after 'dotfiles/after-find-file-adv)
(def-auto-persp "projectile"
:parameters '((dont-save-to-file . t))
:hooks '(after-find-file-hook)
:switch 'frame
:predicate
(lambda (buffer)
(when (and (buffer-file-name)
(projectile-project-p))
(switch-to-buffer (other-buffer))
t))
:get-name-expr
(lambda ()
(if (string-prefix-p dotfiles/directory (file-truename (buffer-file-name (current-buffer))))
dotfiles/directory
(abbreviate-file-name (projectile-project-root)))))
I tried to do the same using the persp-activated-functions
hook, but that doesn't seem to work as reliably:
(add-hook
'persp-activated-functions
(lambda (scope)
(unless (persp-contain-buffer-p (current-buffer))
;; first attempt:
;; (switch-to-buffer (other-buffer))
;; second attempt:
(persp-switch-to-prev-buffer (current-buffer)))))
I'll keep using the auto-persp now and will see if I run into any problems, thanks again for your help!
This is strange. Maybe it's because you are using spacemacs, or whatever in your config...
Maybe you missed the (setq persp-add-buffer-on-find-file 'if-not-autopersp)
thing?
The relevant code is here: https://github.com/Bad-ptr/persp-mode.el/blob/master/persp-mode.el#L1403 maybe you can try to experiment with changing it)
The last snippet posted by @toupeira is not working for me with the latest version from MELPA.
When evaluating the def-auto-persp
form I get a compilation warning: Warning: ‘t’ called as a function
and an error condition-case: Symbol’s function definition is void: closure
@julienfantin can you reproduce it with M-x toggle-debug-on-error RET
(or starting emacs with --debug-init flag) and post the backtrace here?
@julienfantin you can see my current configuration here. You have to remove/change the if
clause in the :get-name-expr
section, that's specific to my setup and requires another variable dotfiles/directory
to be set. I assume you have projectile
installed?
@Bad-ptr
Here is the (hairy) backtrace.
I suspect it's picking up something in my environment since I've managed to make it work by running @toupeira's config with (with-temp-buffer (eval '(def-auto-pers ...)))
!
Debugger entered--Lisp error: (void-function closure)
(closure (after-find-file-hook t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn (switch-to-buffer (other-buffer)) t)))
(funcall (closure (after-find-file-hook t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn (switch-to-buffer (other-buffer)) t))) buffer)
(if (funcall (closure (after-find-file-hook t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn (switch-to-buffer (other-buffer)) t))) buffer) (progn t))
(when (funcall (closure (after-find-file-hook t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn (switch-to-buffer (other-buffer)) t))) buffer) t)
(save-current-buffer (set-buffer buffer) (when (funcall (closure (after-find-file-hook t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn (switch-to-buffer (other-buffer)) t))) buffer) t))
(with-current-buffer buffer (when (funcall (closure (after-find-file-hook t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn (switch-to-buffer (other-buffer)) t))) buffer) t))
(lambda (buffer) (with-current-buffer buffer (when (funcall (closure (after-find-file-hook t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn (switch-to-buffer ...) t))) buffer) t)))(#<buffer config-layouts.el>)
funcall((lambda (buffer) (with-current-buffer buffer (when (funcall (closure (after-find-file-hook t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn (switch-to-buffer ...) t))) buffer) t))) #<buffer config-layouts.el>)
(if (funcall (lambda (buffer) (with-current-buffer buffer (when (funcall (closure (after-find-file-hook t) (_buffer) (if ... ...)) buffer) t))) buffer) (progn (with-current-buffer buffer (let* ((persp-name (funcall (closure ... nil ...))) (persp (persp-add-new persp-name)) (after-match (funcall #[... "\303 \"\210\n\207" [buffer persp after-match persp-add-buffer] 3] persp-name persp buffer hook hook-args (quote frame) (quote ...) nil nil #[... "\300\207" [t] 1])) (do-def-after-match (when (functionp after-match) (funcall after-match persp-name persp buffer hook hook-args ... ... nil nil)))) (when do-def-after-match (funcall #[(persp-name persp buffer hook hook-args switch parameters noauto weak) "\203@� \204�\306H\n>\204�\307\310\311D\"\210\211\312\313I\210)\f\203:�\306H\n>\2042�\307\310\311D\"\210\211\314\313I\210)\315\"\210\316!\210\317\320\"\204r�\321\322\"\203]�\323!\210\202r�\321\324\"\203m�\325!\210\202r�\326!\210\205{�\327!\207" [persp noauto cl-struct-perspective-tags v weak v 0 signal wrong-type-argument perspective 6 t 5 modify-persp-parameters persp-unhide memql ... eql window persp-window-switch frame persp-frame-switch persp-switch persp-switch-to-buffer parameters persp-name switch buffer] 5] persp-name persp buffer hook hook-args (quote frame) (quote (...)) nil nil))))))
(when (funcall (lambda (buffer) (with-current-buffer buffer (when (funcall (closure (after-find-file-hook t) (_buffer) (if ... ...)) buffer) t))) buffer) (with-current-buffer buffer (let* ((persp-name (funcall (closure (after-find-file-hook t) nil (abbreviate-file-name ...)))) (persp (persp-add-new persp-name)) (after-match (funcall #[(persp-name persp buffer hook hook-args switch parameters noauto weak after-match) "\303 \"\210\n\207" [buffer persp after-match persp-add-buffer] 3] persp-name persp buffer hook hook-args (quote frame) (quote (...)) nil nil #[(persp-name persp buffer hook hook-args switch parameters noauto weak) "\300\207" [t] 1])) (do-def-after-match (when (functionp after-match) (funcall after-match persp-name persp buffer hook hook-args (quote frame) (quote ...) nil nil)))) (when do-def-after-match (funcall #[(persp-name persp buffer hook hook-args switch parameters noauto weak) "\203@� \204�\306H\n>\204�\307\310\311D\"\210\211\312\313I\210)\f\203:�\306H\n>\2042�\307\310\311D\"\210\211\314\313I\210)\315\"\210\316!\210\317\320\"\204r�\321\322\"\203]�\323!\210\202r�\321\324\"\203m�\325!\210\202r�\326!\210\205{�\327!\207" [persp noauto cl-struct-perspective-tags v weak v 0 signal wrong-type-argument perspective 6 t 5 modify-persp-parameters persp-unhide memql (quote nil) eql window persp-window-switch frame persp-frame-switch persp-switch persp-switch-to-buffer parameters persp-name switch buffer] 5] persp-name persp buffer hook hook-args (quote frame) (quote ((dont-save-to-file . t))) nil nil)))))
(let nil (unless buffer (setq buffer (current-buffer))) (when (funcall (lambda (buffer) (with-current-buffer buffer (when (funcall (closure ... ... ...) buffer) t))) buffer) (with-current-buffer buffer (let* ((persp-name (funcall (closure ... nil ...))) (persp (persp-add-new persp-name)) (after-match (funcall #[... "\303 \"\210\n\207" [buffer persp after-match persp-add-buffer] 3] persp-name persp buffer hook hook-args (quote frame) (quote ...) nil nil #[... "\300\207" [t] 1])) (do-def-after-match (when (functionp after-match) (funcall after-match persp-name persp buffer hook hook-args ... ... nil nil)))) (when do-def-after-match (funcall #[(persp-name persp buffer hook hook-args switch parameters noauto weak) "\203@� \204�\306H\n>\204�\307\310\311D\"\210\211\312\313I\210)\f\203:�\306H\n>\2042�\307\310\311D\"\210\211\314\313I\210)\315\"\210\316!\210\317\320\"\204r�\321\322\"\203]�\323!\210\202r�\321\324\"\203m�\325!\210\202r�\326!\210\205{�\327!\207" [persp noauto cl-struct-perspective-tags v weak v 0 signal wrong-type-argument perspective 6 t 5 modify-persp-parameters persp-unhide memql ... eql window persp-window-switch frame persp-frame-switch persp-switch persp-switch-to-buffer parameters persp-name switch buffer] 5] persp-name persp buffer hook hook-args (quote frame) (quote (...)) nil nil))))))
(lambda (&optional buffer hook hook-args) (let nil (unless buffer (setq buffer (current-buffer))) (when (funcall (lambda (buffer) (with-current-buffer buffer (when (funcall ... buffer) t))) buffer) (with-current-buffer buffer (let* ((persp-name (funcall ...)) (persp (persp-add-new persp-name)) (after-match (funcall #[... "\303 \"\210\n\207" [buffer persp after-match persp-add-buffer] 3] persp-name persp buffer hook hook-args ... ... nil nil #[... "\300\207" [t] 1])) (do-def-after-match (when ... ...))) (when do-def-after-match (funcall #[... "\203@� \204�\306H\n>\204�\307\310\311D\"\210\211\312\313I\210)\f\203:�\306H\n>\2042�\307\310\311D\"\210\211\314\313I\210)\315\"\210\316!\210\317\320\"\204r�\321\322\"\203]�\323!\210\202r�\321\324\"\203m�\325!\210\202r�\326!\210\205{�\327!\207" [persp noauto cl-struct-perspective-tags v weak v 0 signal wrong-type-argument perspective 6 t 5 modify-persp-parameters persp-unhide memql ... eql window persp-window-switch frame persp-frame-switch persp-switch persp-switch-to-buffer parameters persp-name switch buffer] 5] persp-name persp buffer hook hook-args (quote frame) (quote ...) nil nil)))))))(#<buffer config-layouts.el>)
persp--auto-persp-pickup-buffer(("projectile" (:main-action lambda (&optional buffer hook hook-args) (let nil (unless buffer (setq buffer (current-buffer))) (when (funcall (lambda (buffer) (with-current-buffer buffer (when ... t))) buffer) (with-current-buffer buffer (let* ((persp-name ...) (persp ...) (after-match ...) (do-def-after-match ...)) (when do-def-after-match (funcall #[... "\203@� \204�\306H\n>\204�\307\310\311D\"\210\211\312\313I\210)\f\203:�\306H\n>\2042�\307\310\311D\"\210\211\314\313I\210)\315\"\210\316!\210\317\320\"\204r�\321\322\"\203]�\323!\210\202r�\321\324\"\203m�\325!\210\202r�\326!\210\205{�\327!\207" [persp noauto cl-struct-perspective-tags v weak v 0 signal wrong-type-argument perspective 6 t 5 modify-persp-parameters persp-unhide memql ... eql window persp-window-switch frame persp-frame-switch persp-switch persp-switch-to-buffer parameters persp-name switch buffer] 5] persp-name persp buffer hook hook-args ... ... nil nil))))))) (:generated-predicate lambda (buffer) (with-current-buffer buffer (when (funcall (closure (after-find-file-hook t) (_buffer) (if (and ... ...) (progn ... t))) buffer) t))) (:get-name-expr closure (after-find-file-hook t) nil (abbreviate-file-name (projectile-project-root))) (:predicate closure (after-find-file-hook t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn (switch-to-buffer (other-buffer)) t))) (:switch . frame) (:hooks (config-layouts-after-find-file-hook . #[128 "\205\205�\301\302\204�p\262r\211q\210\303\304\305!\306 \307 \205)�\310 \205)�\311\312 !\210\305#!\2050�\305)\262\205\203�rq\210\303\304\305!\301\313\314 !# \315!\316\317\320\301\211\321&\n\322!\205m�\211\317\320\301\211& \211\205\200�\323 \317\320\301\211& \266\204)\266\203\207" [persp-mode nil config-layouts-after-find-file-hook closure after-find-file-hook t _buffer buffer-file-name projectile-project-p switch-to-buffer other-buffer abbreviate-file-name projectile-project-root persp-add-new #[(persp-name persp buffer hook hook-args switch parameters noauto weak after-match) "\303 \"\210\n\207" [buffer persp after-match persp-add-buffer] 3] frame ((dont-save-to-file . t)) #[(persp-name persp buffer hook hook-args switch parameters noauto weak) "\300\207" [t] 1] functionp #[(persp-name persp buffer hook hook-args switch parameters noauto weak) "\203@� \204�\306H\n>\204�\307\310\311D\"\210\211\312\313I\210)\f\203:�\306H\n>\2042�\307\310\311D\"\210\211\314\313I\210)\315\"\210\316!\210\317\320\"\204r�\321\322\"\203]�\323!\210\202r�\321\324\"\203m�\325!\210\202r�\326!\210\205{�\327!\207" [persp noauto cl-struct-perspective-tags v weak v 0 signal wrong-type-argument perspective 6 t 5 modify-persp-parameters persp-unhide memql (quote nil) eql window persp-window-switch frame persp-frame-switch persp-switch persp-switch-to-buffer parameters persp-name switch buffer] 5]] 18 "\n\n(fn &rest HOOK-ARGS)"])) (:parameters (dont-save-to-file . t))) #<buffer config-layouts.el>)
apply(persp--auto-persp-pickup-buffer (("projectile" (:main-action lambda (&optional buffer hook hook-args) (let nil (unless buffer (setq buffer (current-buffer))) (when (funcall (lambda (buffer) (with-current-buffer buffer ...)) buffer) (with-current-buffer buffer (let* (... ... ... ...) (when do-def-after-match ...)))))) (:generated-predicate lambda (buffer) (with-current-buffer buffer (when (funcall (closure (after-find-file-hook t) (_buffer) (if ... ...)) buffer) t))) (:get-name-expr closure (after-find-file-hook t) nil (abbreviate-file-name (projectile-project-root))) (:predicate closure (after-find-file-hook t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn (switch-to-buffer (other-buffer)) t))) (:switch . frame) (:hooks (config-layouts-after-find-file-hook . #[128 "\205\205�\301\302\204�p\262r\211q\210\303\304\305!\306 \307 \205)�\310 \205)�\311\312 !\210\305#!\2050�\305)\262\205\203�rq\210\303\304\305!\301\313\314 !# \315!\316\317\320\301\211\321&\n\322!\205m�\211\317\320\301\211& \211\205\200�\323 \317\320\301\211& \266\204)\266\203\207" [persp-mode nil config-layouts-after-find-file-hook closure after-find-file-hook t _buffer buffer-file-name projectile-project-p switch-to-buffer other-buffer abbreviate-file-name projectile-project-root persp-add-new #[(persp-name persp buffer hook hook-args switch parameters noauto weak after-match) "\303 \"\210\n\207" [buffer persp after-match persp-add-buffer] 3] frame ((dont-save-to-file . t)) #[(persp-name persp buffer hook hook-args switch parameters noauto weak) "\300\207" [t] 1] functionp #[(persp-name persp buffer hook hook-args switch parameters noauto weak) "\203@� \204�\306H\n>\204�\307\310\311D\"\210\211\312\313I\210)\f\203:�\306H\n>\2042�\307\310\311D\"\210\211\314\313I\210)\315\"\210\316!\210\317\320\"\204r�\321\322\"\203]�\323!\210\202r�\321\324\"\203m�\325!\210\202r�\326!\210\205{�\327!\207" [persp noauto cl-struct-perspective-tags v weak v 0 signal wrong-type-argument perspective 6 t 5 modify-persp-parameters persp-unhide memql ... eql window persp-window-switch frame persp-frame-switch persp-switch persp-switch-to-buffer parameters persp-name switch buffer] 5]] 18 "\n\n(fn &rest HOOK-ARGS)"])) (:parameters (dont-save-to-file . t))) #<buffer config-layouts.el>))
#[128 "\302\300\303\301\"\"\207" [persp--auto-persp-pickup-buffer (("projectile" (:main-action lambda (&optional buffer hook hook-args) (let nil (unless buffer (setq buffer ...)) (when (funcall ... buffer) (with-current-buffer buffer ...)))) (:generated-predicate lambda (buffer) (with-current-buffer buffer (when (funcall ... buffer) t))) (:get-name-expr closure (after-find-file-hook t) nil (abbreviate-file-name (projectile-project-root))) (:predicate closure (after-find-file-hook t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn (switch-to-buffer ...) t))) (:switch . frame) (:hooks (config-layouts-after-find-file-hook . #[128 "\205\205�\301\302\204�p\262r\211q\210\303\304\305!\306 \307 \205)�\310 \205)�\311\312 !\210\305#!\2050�\305)\262\205\203�rq\210\303\304\305!\301\313\314 !# \315!\316\317\320\301\211\321&\n\322!\205m�\211\317\320\301\211& \211\205\200�\323 \317\320\301\211& \266\204)\266\203\207" [persp-mode nil config-layouts-after-find-file-hook closure after-find-file-hook t _buffer buffer-file-name projectile-project-p switch-to-buffer other-buffer abbreviate-file-name projectile-project-root persp-add-new #[... "\303 \"\210\n\207" [buffer persp after-match persp-add-buffer] 3] frame ... #[... "\300\207" [t] 1] functionp #[... "\203@� \204�\306H\n>\204�\307\310\311D\"\210\211\312\313I\210)\f\203:�\306H\n>\2042�\307\310\311D\"\210\211\314\313I\210)\315\"\210\316!\210\317\320\"\204r�\321\322\"\203]�\323!\210\202r�\321\324\"\203m�\325!\210\202r�\326!\210\205{�\327!\207" [persp noauto cl-struct-perspective-tags v weak v 0 signal wrong-type-argument perspective 6 t 5 modify-persp-parameters persp-unhide memql ... eql window persp-window-switch frame persp-frame-switch persp-switch persp-switch-to-buffer parameters persp-name switch buffer] 5]] 18 "\n\n(fn &rest HOOK-ARGS)"])) (:parameters (dont-save-to-file . t)))) apply append] 6 "\n\n(fn &rest ARGS2)"](#<buffer config-layouts.el>)
mapc(#[128 "\302\300\303\301\"\"\207" [persp--auto-persp-pickup-buffer (("projectile" (:main-action lambda (&optional buffer hook hook-args) (let nil (unless buffer (setq buffer ...)) (when (funcall ... buffer) (with-current-buffer buffer ...)))) (:generated-predicate lambda (buffer) (with-current-buffer buffer (when (funcall ... buffer) t))) (:get-name-expr closure (after-find-file-hook t) nil (abbreviate-file-name (projectile-project-root))) (:predicate closure (after-find-file-hook t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn (switch-to-buffer ...) t))) (:switch . frame) (:hooks (config-layouts-after-find-file-hook . #[128 "\205\205�\301\302\204�p\262r\211q\210\303\304\305!\306 \307 \205)�\310 \205)�\311\312 !\210\305#!\2050�\305)\262\205\203�rq\210\303\304\305!\301\313\314 !# \315!\316\317\320\301\211\321&\n\322!\205m�\211\317\320\301\211& \211\205\200�\323 \317\320\301\211& \266\204)\266\203\207" [persp-mode nil config-layouts-after-find-file-hook closure after-find-file-hook t _buffer buffer-file-name projectile-project-p switch-to-buffer other-buffer abbreviate-file-name projectile-project-root persp-add-new #[... "\303 \"\210\n\207" [buffer persp after-match persp-add-buffer] 3] frame ... #[... "\300\207" [t] 1] functionp #[... "\203@� \204�\306H\n>\204�\307\310\311D\"\210\211\312\313I\210)\f\203:�\306H\n>\2042�\307\310\311D\"\210\211\314\313I\210)\315\"\210\316!\210\317\320\"\204r�\321\322\"\203]�\323!\210\202r�\321\324\"\203m�\325!\210\202r�\326!\210\205{�\327!\207" [persp noauto cl-struct-perspective-tags v weak v 0 signal wrong-type-argument perspective 6 t 5 modify-persp-parameters persp-unhide memql ... eql window persp-window-switch frame persp-frame-switch persp-switch persp-switch-to-buffer parameters persp-name switch buffer] 5]] 18 "\n\n(fn &rest HOOK-ARGS)"])) (:parameters (dont-save-to-file . t)))) apply append] 6 "\n\n(fn &rest ARGS2)"] (#<buffer config-layouts.el> #<buffer config-windows.el> #<buffer *Minibuf-1*> #<buffer *Minibuf-2*> #<buffer config-modeline.el> #<buffer init.el> #<buffer *scratch*> #<buffer *Minibuf-0*> #<buffer *Messages*> #<buffer *code-conversion-work*> #<buffer *Echo Area 0*> #<buffer *Echo Area 1*> #<buffer *Warnings*> #<buffer *diff-hl* > #<buffer *counsel*> #<buffer *Packages*> #<buffer *which-key*> #<buffer *Compile-Log*>))
persp-auto-persp-pickup-bufferlist-for("projectile" (#<buffer config-layouts.el> #<buffer config-windows.el> #<buffer *Minibuf-1*> #<buffer *Minibuf-2*> #<buffer config-modeline.el> #<buffer init.el> #<buffer *scratch*> #<buffer *Minibuf-0*> #<buffer *Messages*> #<buffer *code-conversion-work*> #<buffer *Echo Area 0*> #<buffer *Echo Area 1*> #<buffer *Warnings*> #<buffer *diff-hl* > #<buffer *counsel*> #<buffer *Packages*> #<buffer *which-key*> #<buffer *Compile-Log*>))
persp-auto-persp-pickup-buffers-for("projectile")
def-auto-persp("projectile" :parameters ((dont-save-to-file . t)) :hooks (config-layouts-after-find-file-hook) :switch frame :predicate (closure (after-find-file-hook t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn (switch-to-buffer (other-buffer)) t))) :get-name-expr (closure (after-find-file-hook t) nil (abbreviate-file-name (projectile-project-root))))
(closure (after-find-file-hook t) nil (defvar config-layouts-after-find-file-hook nil) (def-auto-persp "projectile" :parameters (quote ((dont-save-to-file . t))) :hooks (quote (config-layouts-after-find-file-hook)) :switch (quote frame) :predicate (function (lambda (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn (switch-to-buffer (other-buffer)) t)))) :get-name-expr (function (lambda nil (abbreviate-file-name (projectile-project-root))))))()
eval-after-load(persp-mode (closure (after-find-file-hook t) nil (defvar config-layouts-after-find-file-hook nil) (def-auto-persp "projectile" :parameters (quote ((dont-save-to-file . t))) :hooks (quote (config-layouts-after-find-file-hook)) :switch (quote frame) :predicate (function (lambda (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn (switch-to-buffer (other-buffer)) t)))) :get-name-expr (function (lambda nil (abbreviate-file-name (projectile-project-root)))))))
(closure (after-find-file-hook t) nil (eval-after-load (quote persp-mode) (function (lambda nil (defvar config-layouts-after-find-file-hook nil) (def-auto-persp "projectile" :parameters (quote ((dont-save-to-file . t))) :hooks (quote (config-layouts-after-find-file-hook)) :switch (quote frame) :predicate (function (lambda (_buffer) (if ... ...))) :get-name-expr (function (lambda nil (abbreviate-file-name ...))))))))()
eval-after-load(projectile (closure (after-find-file-hook t) nil (eval-after-load (quote persp-mode) (function (lambda nil (defvar config-layouts-after-find-file-hook nil) (def-auto-persp "projectile" :parameters (quote ((dont-save-to-file . t))) :hooks (quote (config-layouts-after-find-file-hook)) :switch (quote frame) :predicate (function (lambda (_buffer) (if ... ...))) :get-name-expr (function (lambda nil (abbreviate-file-name ...)))))))))
(progn (eval-after-load (quote projectile) (function (lambda nil (eval-after-load (quote persp-mode) (function (lambda nil (defvar config-layouts-after-find-file-hook nil) (def-auto-persp "projectile" :parameters ... :hooks ... :switch ... :predicate ... :get-name-expr ...))))))))
(progn (defvar after-find-file-hook) (progn (eval-after-load (quote projectile) (function (lambda nil (eval-after-load (quote persp-mode) (function (lambda nil ... ...))))))))
eval((progn (defvar after-find-file-hook) (progn (eval-after-load (quote projectile) (function (lambda nil (eval-after-load (quote persp-mode) (function (lambda nil ... ...)))))))) t)
edebug-eval-defun(nil)
apply(edebug-eval-defun nil)
eval-defun(nil)
funcall-interactively(eval-defun nil)
call-interactively(eval-defun nil nil)
command-execute(eval-defun)
@julienfantin I think it must be fixed by https://github.com/Bad-ptr/persp-mode.el/commit/5d7e9755a1e5606c63f4832d7d69a979c679696b
@Bad-ptr thanks for looking into this, but with version 20160924.308
from MELPA, I'm still getting:
Debugger entered--Lisp error: (void-function closure)
(closure (t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn t)))
(funcall (closure (t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn t))) buffer)
(if (funcall (closure (t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn t))) buffer) (progn t))
(when (funcall (closure (t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn t))) buffer) t)
(save-current-buffer (set-buffer buffer) (when (funcall (closure (t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn t))) buffer) t))
(with-current-buffer buffer (when (funcall (closure (t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn t))) buffer) t))
(lambda (buffer) (with-current-buffer buffer (when (funcall (closure (t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn t))) buffer) t)))(#<buffer *scratch*>)
funcall((lambda (buffer) (with-current-buffer buffer (when (funcall (closure (t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn t))) buffer) t))) #<buffer *scratch*>)
(if (funcall (lambda (buffer) (with-current-buffer buffer (when (funcall (closure (t) (_buffer) (if ... ...)) buffer) t))) buffer) (progn (with-current-buffer buffer (let* ((persp-name (funcall (closure ... nil ...))) (persp (persp-add-new persp-name)) (after-match (funcall (quote #[... "\303 \"\210\n\207" [buffer persp after-match persp-add-buffer] 3]) persp-name persp buffer hook hook-args (quote frame) (quote ...) nil nil (quote #[... "\300\207" [t] 1]))) (do-def-after-match (when (functionp after-match) (funcall after-match persp-name persp buffer hook hook-args ... ... nil nil)))) (when do-def-after-match (funcall (quote #[... "\203@ \204 \306H\n>\204 \307\310\311D\"\210\211\312\313I\210)\f\203: \306H\n>\2042 \307\310\311D\"\210\211\314\313I\210)\315\"\210\316!\210\317\320\"\204r \321\322\"\203] \323!\210\202r \321\324\"\203m \325!\210\202r \326!\210\205{ \327!\207" [persp noauto cl-struct-perspective-tags v weak v 0 signal wrong-type-argument perspective 6 t 5 modify-persp-parameters persp-unhide memql ... eql window persp-window-switch frame persp-frame-switch persp-switch persp-switch-to-buffer parameters persp-name switch buffer] 5]) persp-name persp buffer hook hook-args (quote frame) (quote (...)) nil nil))))))
(when (funcall (lambda (buffer) (with-current-buffer buffer (when (funcall (closure (t) (_buffer) (if ... ...)) buffer) t))) buffer) (with-current-buffer buffer (let* ((persp-name (funcall (closure (t) nil (abbreviate-file-name ...)))) (persp (persp-add-new persp-name)) (after-match (funcall (quote #[... "\303 \"\210\n\207" [buffer persp after-match persp-add-buffer] 3]) persp-name persp buffer hook hook-args (quote frame) (quote (...)) nil nil (quote #[... "\300\207" [t] 1]))) (do-def-after-match (when (functionp after-match) (funcall after-match persp-name persp buffer hook hook-args (quote frame) (quote ...) nil nil)))) (when do-def-after-match (funcall (quote #[(persp-name persp buffer hook hook-args switch parameters noauto weak) "\203@ \204 \306H\n>\204 \307\310\311D\"\210\211\312\313I\210)\f\203: \306H\n>\2042 \307\310\311D\"\210\211\314\313I\210)\315\"\210\316!\210\317\320\"\204r \321\322\"\203] \323!\210\202r \321\324\"\203m \325!\210\202r \326!\210\205{ \327!\207" [persp noauto cl-struct-perspective-tags v weak v 0 signal wrong-type-argument perspective 6 t 5 modify-persp-parameters persp-unhide memql ... eql window persp-window-switch frame persp-frame-switch persp-switch persp-switch-to-buffer parameters persp-name switch buffer] 5]) persp-name persp buffer hook hook-args (quote frame) (quote ((dont-save-to-file . t))) nil nil)))))
(let nil (unless buffer (setq buffer (current-buffer))) (when (funcall (lambda (buffer) (with-current-buffer buffer (when (funcall (closure ... ... ...) buffer) t))) buffer) (with-current-buffer buffer (let* ((persp-name (funcall (closure ... nil ...))) (persp (persp-add-new persp-name)) (after-match (funcall (quote #[... "\303 \"\210\n\207" [buffer persp after-match persp-add-buffer] 3]) persp-name persp buffer hook hook-args (quote frame) (quote ...) nil nil (quote #[... "\300\207" [t] 1]))) (do-def-after-match (when (functionp after-match) (funcall after-match persp-name persp buffer hook hook-args ... ... nil nil)))) (when do-def-after-match (funcall (quote #[... "\203@ \204 \306H\n>\204 \307\310\311D\"\210\211\312\313I\210)\f\203: \306H\n>\2042 \307\310\311D\"\210\211\314\313I\210)\315\"\210\316!\210\317\320\"\204r \321\322\"\203] \323!\210\202r \321\324\"\203m \325!\210\202r \326!\210\205{ \327!\207" [persp noauto cl-struct-perspective-tags v weak v 0 signal wrong-type-argument perspective 6 t 5 modify-persp-parameters persp-unhide memql ... eql window persp-window-switch frame persp-frame-switch persp-switch persp-switch-to-buffer parameters persp-name switch buffer] 5]) persp-name persp buffer hook hook-args (quote frame) (quote (...)) nil nil))))))
(lambda (&optional buffer hook hook-args) (let nil (unless buffer (setq buffer (current-buffer))) (when (funcall (lambda (buffer) (with-current-buffer buffer (when (funcall ... buffer) t))) buffer) (with-current-buffer buffer (let* ((persp-name (funcall ...)) (persp (persp-add-new persp-name)) (after-match (funcall ... persp-name persp buffer hook hook-args ... ... nil nil ...)) (do-def-after-match (when ... ...))) (when do-def-after-match (funcall (quote #[... "\203@ \204 \306H\n>\204 \307\310\311D\"\210\211\312\313I\210)\f\203: \306H\n>\2042 \307\310\311D\"\210\211\314\313I\210)\315\"\210\316!\210\317\320\"\204r \321\322\"\203] \323!\210\202r \321\324\"\203m \325!\210\202r \326!\210\205{ \327!\207" [persp noauto cl-struct-perspective-tags v weak v 0 signal wrong-type-argument perspective 6 t 5 modify-persp-parameters persp-unhide memql ... eql window persp-window-switch frame persp-frame-switch persp-switch persp-switch-to-buffer parameters persp-name switch buffer] 5]) persp-name persp buffer hook hook-args (quote frame) (quote ...) nil nil)))))))(#<buffer *scratch*>)
persp--auto-persp-pickup-buffer(("projectile" (:main-action lambda (&optional buffer hook hook-args) (let nil (unless buffer (setq buffer (current-buffer))) (when (funcall (lambda (buffer) (with-current-buffer buffer (when ... t))) buffer) (with-current-buffer buffer (let* ((persp-name ...) (persp ...) (after-match ...) (do-def-after-match ...)) (when do-def-after-match (funcall ... persp-name persp buffer hook hook-args ... ... nil nil))))))) (:generated-predicate lambda (buffer) (with-current-buffer buffer (when (funcall (closure (t) (_buffer) (if (and ... ...) (progn t))) buffer) t))) (:get-name-expr closure (t) nil (abbreviate-file-name (projectile-project-root))) (:predicate closure (t) (_buffer) (if (and (buffer-file-name) (projectile-project-p)) (progn t))) (:switch . frame) (:hooks (config-layouts-after-find-file-hook . #[(&rest hook-args) "\205{ \306\307 \211\204 prq\210\310\311 \312 \313 \205&
I'm trying to automatically use project layouts for files that belong to a project, what I have so far is the following:
I had to add the checks for
buffer-file-name
andprojectile-project-buffer-p
to avoid issues with things like Helm, but otherwise this seems to work nicely. So my question is basically: do you see any problems with this approach, or maybe there's a more straight-forward or reliable way to accomplish the same thing?