0

I use pyenv to maintain my python versions and virtualenvs. I really like the way you can create a local .python-version for each project, pointing to the version I need. I use pyenv-mode which allows me to set the right pyenv version pretty easily. The problem is that I tend to keep a single emacs server running, so when I switch between buffers in different projects I have to manually switch my pyenv, and if the python version is different I also have to restart the RPC server. I'm trying to automate this, and I found a great library to enable me to run hooks when I switch buffers (https://github.com/10sr/switch-buffer-functions-el).

Here's what I have so far, but it doesn't seem to be working at all (neither the if or then clauses execute):

(add-hook 'switch-buffer-functions
          (lambda (prev cur)
            (if (string-equal "Python" (format-mode-line mode-name nil nil (get-buffer cur)))
                (lambda ()
                  (message "Switching python buffer")
                  (pyenv-use-corresponding)
                  (elpy-rpc-restart))
              (lambda ()
                (message "Switched to non-python buffer"))
              )))

however if I do something like:

(add-hook 'switch-buffer-functions
          (lambda (prev cur)
            (message (format-mode-line mode-name nil nil (get-buffer cur)))))

it seems like it should work as expected as it does print the mode-name. I also tested the if comparison with M-: and it seems to work.... anyone see what I'm doing wrong?

2 Answers 2

0

Looks like what I needed was progn instead of a lambda function. My full working code now, including a check for only re-starting elpy-rpc if the pyenv actually changed (so that it's not constantly restarting it when switching to MiniBuffer)

(use-package switch-buffer-functions
  :config
  (add-hook 'switch-buffer-functions
            (lambda (prev cur)
              (if (string-equal "Python" (format-mode-line mode-name nil nil cur))
                  (progn
                    (setq old_pyenv (pyenv--active-python-version))
                    (pyenv-use-corresponding)
                    (setq new_pyenv (pyenv--active-python-version))

                    (if (not (string-equal old_pyenv new_pyenv))
                        (message "restarting rpc")
                        (elpy-rpc-restart))
                    )
                )))
)
0

Another way to go is to use https://github.com/direnv/direnv to manage the pipenv activation in your shell. This way the env var manipulation happens whenever you change directories in your shell.

Then for Emacs use https://github.com/wbolster/emacs-direnv, which integrates direnv into Emacs when buffers are switched. You might still need to hook in to switch-buffer-functions to restart elpy stuff as needed though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.