Skip to content

Commit

Permalink
Implement pyvenv-tracking-mode
Browse files Browse the repository at this point in the history
The pyvenv-tracking-mode changes the virtual environment on changing focus
between buffers.
  • Loading branch information
dalanicolai authored and smile13241324 committed Sep 14, 2020
1 parent 2b4fd06 commit 1147e75
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 24 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.develop
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ sane way, here is the complete list of changed key bindings
- New keybinding for =org-table-field-info= ~SPC m t f~
(thanks to Dominik Schrempf)
***** Python
- fix/implement pyvenv-tracking-mode (thanks to Daniel Nicolai)
- Key bindings (thanks to Danny Freeman):
- Changed ~SPC m s F~ to ~SPC m e F~ for =lisp-eval-defun-and-go=
- Changed ~SPC m s R~ to ~SPC m e R~ for =lisp-eval-region-and-go=
Expand Down
30 changes: 21 additions & 9 deletions layers/+lang/python/README.org
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
- [[#pyvenv-pyenv-and-pipenv][Pyvenv, pyenv and pipenv]]
- [[#management-of-python-versions-and-virtual-environments][Management of Python versions and virtual environments]]
- [[#manage-virtual-environments-with-pyvenv][Manage virtual environments with pyvenv]]
- [[#automatic-activation-of-local-virtual-environment][Automatic activation of local virtual environment]]
- [[#manage-multiple-python-versions-with-pyenv][Manage multiple Python versions with pyenv]]
- [[#automatic-activation-of-local-pyenv-version][Automatic activation of local pyenv version]]
- [[#manage-environments-and-packages-with-pipenv][Manage environments and packages with pipenv]]
Expand Down Expand Up @@ -364,6 +365,26 @@ by the [[https://github.com/jorgenschaefer/pyvenv][pyvenv]] package. It provides
| ~SPC m V d~ | deactivate active virtual environment |
| ~SPC m V w~ | work on virtual environment in =WORKON_HOME= |

*** Automatic activation of local virtual environment
By default Spacemacs uses the [[https://github.com/jorgenschaefer/pyvenv][pyvenv]] package to manage virtual environments.
Additionally it uses =pyvenv-tracking-mode= to activate a buffer's local virtual
environment on change of focus. Pyvenv determines which virtual environment to
use from the value of the =pyvenv-workon= or the =pyvenv-activate=
buffer-local-variable. Spacemacs scans the project directory for a pattern
=.venv=. If the found =.venv= is a directory then it sets that directory as the
local virtual environment path. If the =.venv= pattern is a file then it checks if
its first line matches an existing path and if so, it sets it as the local
virtual environment path. Finally it checks if it finds an existing directory
with the name of the first line in the ~pyvenv-workon-home~ directory. By default
Spacemacs scans for a virtual environment and sets the local =pyvenv-workon= or
the =pyvenv-activate= variables on visiting a file, but switches virtual
environment on every change of focus using the local variables. The buffer
tracking behavior can be disabled by setting the value of the customizable
variable =pyvenv-tracking-mode= to =nil=. The scanning behavior can be set via the
variable =python-auto-set-local-pyvenv-virtualenv= to:
- =on-visit= (default) set the virtualenv when you visit a python buffer,
- =on-project-switch= set the virtualenv when you switch projects,
- =nil= to disable.
** Manage multiple Python versions with pyenv
If you need multiple Python versions (e.g. Python 2 and Python 3) then take a
look at [[https://github.com/yyuu/pyenv][pyenv]]. It enables the installation and management of multiple
Expand All @@ -390,15 +411,6 @@ the pyenv version. The behavior can be set with the variable
- =on-project-switch= set the version when you switch projects,
- =nil= to disable.

The same is also possible on pyvenv with a file called =.venv= that specifies
either an absolute or relative path to a virtualenv directory. A relative path
is checked relative to the location of =.venv=, then relative to
=pyvenv-workon-home=. =.venv= can also be a virtualenv directory. The behavior
can be set with the variable =python-auto-set-local-pyvenv-virtualenv= to:
- =on-visit= (default) set the virtualenv when you visit a python buffer,
- =on-project-switch= set the virtualenv when you switch projects,
- =nil= to disable.

** Manage environments and packages with pipenv
[[https://pipenv.kennethreitz.org/en/latest/][Pipenv]] is the new standard tool to manage your virtual environments. It can act as
a replacement for both =pyenv= and =venv= on a per-repository basis. An overview
Expand Down
31 changes: 16 additions & 15 deletions layers/+lang/python/funcs.el
Original file line number Diff line number Diff line change
Expand Up @@ -231,21 +231,22 @@ location of \".venv\" file, then relative to pyvenv-workon-home()."
(let ((root-path (locate-dominating-file default-directory ".venv")))
(when root-path
(let ((file-path (expand-file-name ".venv" root-path)))
(if (file-directory-p file-path)
(pyvenv-activate file-path)
(let* ((virtualenv-path-in-file
(with-temp-buffer
(insert-file-contents-literally file-path)
(buffer-substring-no-properties (line-beginning-position)
(line-end-position))))
(virtualenv-abs-path
(if (file-name-absolute-p virtualenv-path-in-file)
virtualenv-path-in-file
(format "%s/%s" root-path virtualenv-path-in-file))))
(if (file-directory-p virtualenv-abs-path)
(pyvenv-activate virtualenv-abs-path)
(pyvenv-workon virtualenv-path-in-file))))))))

(cond ((file-directory-p file-path)
(pyvenv-activate file-path) (setq-local pyvenv-activate file-path))
(t (let* ((virtualenv-path-in-file
(with-temp-buffer
(insert-file-contents-literally file-path)
(buffer-substring-no-properties (line-beginning-position)
(line-end-position))))
(virtualenv-abs-path
(if (file-name-absolute-p virtualenv-path-in-file)
virtualenv-path-in-file
(format "%s/%s" root-path virtualenv-path-in-file))))
(cond ((file-directory-p virtualenv-abs-path)
(pyvenv-activate virtualenv-abs-path)
(setq-local pyvenv-activate virtualenv-abs-path))
(t (pyvenv-workon virtualenv-path-in-file)
(setq-local pyvenv-workon virtualenv-path-in-file))))))))))

;; Tests

Expand Down
1 change: 1 addition & 0 deletions layers/+lang/python/packages.el
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@
:defer t
:init
(progn
(add-hook 'python-mode-hook #'pyvenv-tracking-mode)
(pcase python-auto-set-local-pyvenv-virtualenv
(`on-visit
(dolist (m spacemacs--python-pyvenv-modes)
Expand Down

0 comments on commit 1147e75

Please sign in to comment.