Bad-ptr / persp-mode.el

named perspectives(set of buffers/window configs) for emacs
403 stars 44 forks source link

Auto-complete or Helm to persp-save-to-file-by-names? #22

Closed jluttine closed 8 years ago

jluttine commented 8 years ago

I like to have each layout/perspective in a separate file. This is possible with at least persp-save-to-file-by-names by giving the perspective name. However, this can be a bit annoying and error-prone, if perspective names are long. Would it be a good idea to have auto-complete or Helm support for giving the names? It was suggested here: https://github.com/syl20bnr/spacemacs/pull/3925

Or is there some other convenient way to save each perspective to its own file? I noticed there was something about persp-file. Can it be used to define a filename for each perspective and then they would be saved to their own files automatically when saving layouts? I couldn't figure out how to do this..

Bad-ptr commented 8 years ago

Would it be a good idea to have auto-complete or Helm support for giving the names?

Done 3ce5b5c24b4f589314114f5dbdd6f37c12d3c2c5. However I dont personally use Helm and don't know how to add support for it.)

I noticed there was something about persp-file. Can it be used to define a filename for each perspective and then they would be saved to their own files automatically when saving layouts?

Yes, the persp-file was conceived to do what you want.(not sure how well I implemented that idea cause it turned out that I never used this functionality). After 214bc522898e59783a4a93fc959e702c60168395 the persp-file parameter will also be set by persp-save-to-file-by-names. Hope this will help.

jluttine commented 8 years ago

Quickly tried and looks great. Thanks!

But still I couldn't figure out how to save a layout without Emacs prompting me about which layouts to save and to which file. I'd like to save those layouts into those files in the way I loaded them. And then I'd like to add a hook that when Emacs closes or the layout is closed, it would save that layout. Or something similar. My goal is that I wouldn't need to explicitly save the layout and I could just open the file project1-layout and I could continue Project 1 from where I left off. Is this possible?

Bad-ptr commented 8 years ago

But still I couldn't figure out how to save a layout without Emacs prompting me about which layouts to save and to which file. I'd like to save those layouts into those files in the way I loaded them.

I think that it already works this way.

Suppose you started emacs and activated persp-mode. You start with a single perspective(or you can call it a "layout") -- the default one, which is a special kind of 'layout' because it always contains all buffers. Each perspective(or layout) has parameters -- the association list in the form of ((param-name . param-value) ...). When you create new layout it has no parameters. When you save layout with persp-save-to-file-by-names this function will set the persp-file parameter of the layout(actually for this to happen the persp-auto-save-persps-to-their-file variable must be t so check it). Then when you call persp-save-state-to-file(or it's called from emacs-kill-hook) these layouts will be saved to their files. Try it and if it doesn't work -- then give me a recipe of what you are actually doing, step by step.

or the layout is closed

//hmm... may be I can add a function like persp-safe-kill that will ask user whether he want to save the layout before killing.

I could just open the file project1-layout and I could continue Project 1 from where I left off. Is this possible?

Yes, why not?) You can load it with persp-load-state-from-file.

jluttine commented 8 years ago

Thanks a lot, I'll try these! :+1:

jluttine commented 8 years ago

Ok, I think autosaving works, nice!

However, if I have a Python REPL buffer (Inferior Python) in one window, that window is closed when the layout is loaded. I thought this happens because REPL is not running when the layout is loaded, but even if I start the REPL before loading the layout, the REPL window is not there. It doesn't even work if I do the following:

If I put some other buffer to the REPL window and save the layout, then it's loaded correctly with that non-REPL window.

I've also added REPL starting command to persp-activated-hook to get REPL started along with the layout loading.

jluttine commented 8 years ago

One workaround:

Bad-ptr commented 8 years ago

I thought this happens because REPL is not running when the layout is loaded,

Yes, that is the case.

I've also added REPL starting command to persp-activated-hook to get REPL started

This hook runs after the window configurating is restored so it will not work as you expect. Here 0264d2742ae3d6bf59d0c8d93aa9b66e0f638ca5 I have added the persp-before-switch-functions hook which you can use.

You can also add save/restore functions for python repl, something like:

(with-eval-after-load "persp-mode-autoloads"
  (add-to-list 'persp-save-buffer-functions
               #'(lambda (b)
                   (when (eq 'inferior-python-mode (buffer-local-value 'major-mode b))
                     `(def-inferior-python-buffer ,(buffer-name b)))))
  (add-to-list 'persp-load-buffer-functions
               #'(lambda (savelist)
                   (when (eq (car savelist) 'def-inferior-python-buffer)
                     (run-python nil nil nil)
                     (with-current-buffer (python-shell-get-buffer)
                       (rename-buffer (cadr savelist))
                       (current-buffer))))))
jluttine commented 8 years ago

Thanks, I'll look into these. :yum:

lethjakman commented 8 years ago

+1 for helm support. I'd offer a PR, but honestly I don't know either.

Bad-ptr commented 8 years ago

Ok, I wrote something to support buffer filtering in helm:

(with-eval-after-load "persp-mode-autoloads"
  (defun helm-persp-buffer-list-bridge
      (prompt _collection &optional test _require-match init hist default _inherit-im name buffer)
    (or
     (helm :sources (helm-build-in-buffer-source name
                      :init (lambda () (helm-init-candidates-in-buffer 'global
                                    (mapcar #'(lambda (b) (buffer-name b))
                                            (persp-buffer-list-restricted))))
                      :fuzzy-match helm-mode-fuzzy-match)
           :fuzzy-match helm-mode-fuzzy-match
           :prompt prompt
           :buffer buffer
           :input init
           :history hist
           :resume 'noresume
           :default (or default ""))
     (helm-mode--keyboard-quit)))

  (with-eval-after-load "helm-mode"
    (setq helm-completing-read-handlers-alist
          (append '((switch-to-buffer                 . helm-persp-buffer-list-bridge)
                    (kill-buffer                      . helm-persp-buffer-list-bridge)
                    (persp-temporarily-display-buffer . helm-persp-buffer-list-bridge)
                    (persp-add-buffer                 . helm-persp-buffer-list-bridge)
                    (persp-remove-buffer              . helm-persp-buffer-list-bridge))
                  helm-completing-read-handlers-alist))))
Bad-ptr commented 8 years ago

I consider it as solved.) If you have any question feel free to ask.

Bad-ptr commented 8 years ago

In the case if somebody will search here for a helm support: https://github.com/Bad-ptr/persp-mode.el#helm