From dca81ac8c681dc264637f7b14146be13bbf8e1fd Mon Sep 17 00:00:00 2001 From: Daniel Kraus Date: Thu, 20 Jul 2017 15:24:24 +0800 Subject: [PATCH] Make auto-workon work with text files containing virtualenv name This way you can keep all your virtualenvs in one place and can reuse the same virtualenv for multiple projects. Virtualfish (virtualenvwrapper for fish shell) does this as well, see: http://virtualfish.readthedocs.io/en/latest/plugins.html#auto-activation-auto-activation --- README.md | 9 +++++---- test/virtualenvwrapper-test.el | 18 ++++++++++++++++++ virtualenvwrapper.el | 17 ++++++++++++----- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index acb4f0f..368d33a 100644 --- a/README.md +++ b/README.md @@ -330,10 +330,11 @@ instead: (projectile-find-file))) ``` -As long as a virtualenv is found in the `projectile-project-root` and -whose name is in the list `venv-dirlookup-names` it will be -automatically activated. By default, it's value is `'(".venv", "venv")'`, -but you can set if however you like to match your naming conventions: +As long as a virtualenv or a text file with the name of the virtualenv is +found in the `projectile-project-root` and whose name is in the list +`venv-dirlookup-names` it will be automatically activated. By default, it's +value is `'(".venv", "venv")'`, but you can set if however you like to match +your naming conventions: ```lisp (setq venv-dirlookup-names '(".venv" "pyenv" ".virtual")) diff --git a/test/virtualenvwrapper-test.el b/test/virtualenvwrapper-test.el index 837b520..2dd3f3e 100644 --- a/test/virtualenvwrapper-test.el +++ b/test/virtualenvwrapper-test.el @@ -210,3 +210,21 @@ (venv-deactivate) (venv-projectile-auto-workon) (assert-venv-activated))))) + +(ert-deftest venv-projectile-auto-workon-works-with-text-file () + (with-temp-env + venv-tmp-env + ;; the reason for setting a bogus venv-location here is that the + ;; venv-location shouldn't matter, projectile-auto-workon should happen + ;; indepedent of it's being set or not + (let* ((venv-location "bogus") + ;; Create a file in the projectile-project-root with + ;; the text content of the venv to be activated + (venv-tmp-text-file (make-temp-file "venv" nil nil venv-tmp-env)) + (venv-tmp-text-name (file-name-nondirectory venv-tmp-text-file))) + (noflet ((projectile-project-root () temporary-file-directory)) + (setq venv-dirlookup-names (list venv-tmp-text-name)) + (venv-deactivate) + (venv-projectile-auto-workon) + (assert-venv-activated) + (delete-file venv-tmp-text-file))))) diff --git a/virtualenvwrapper.el b/virtualenvwrapper.el index ce2e898..0708eb0 100644 --- a/virtualenvwrapper.el +++ b/virtualenvwrapper.el @@ -95,12 +95,19 @@ to activate when one of them is found." "If a venv in the projetile root exists, activates it. Set your common venvs names in `venv-dirlookup-names'" (let ((path (--first - (file-exists-p it) - (--map (concat (projectile-project-root) it) - venv-dirlookup-names)))) + (file-exists-p it) + (--map (concat (projectile-project-root) it) + venv-dirlookup-names)))) (when path - (setq venv-current-name path) ;; there's really nothing that feels good to do here ;_; - (venv--activate-dir path)))) + ;; If the PATH is a regular and readable file, read the first + ;; string in this file and use it to active the virtualenv. + (if (and path (file-regular-p path) (file-readable-p path)) + (with-temp-buffer + (insert-file-contents path) + (venv-workon (car (split-string (buffer-string) "\n" t)))) + ;; PATH is not a file, assume it's a virtualenv directory and activate it + (setq venv-current-name path) ;; there's really nothing that feels good to do here ;_; + (venv--activate-dir path))))) ;; internal utility functions