| @@ -2021,18 +2021,22 @@ This variable is intended to be explicitly set by user. | |||||
| When nil, `with-venv' tries to find suitable venv dir.") | When nil, `with-venv' tries to find suitable venv dir.") | ||||
| (defmacro with-venv-dir (dir &rest body) | (defmacro with-venv-dir (dir &rest body) | ||||
| "Set python environment to DIR and execute BODY." | |||||
| "Set python environment to DIR and execute BODY. | |||||
| This macro does not check if DIR is a valid python environemnt. | |||||
| If dir is nil, execute BODY as usual." | |||||
| `(let ((--with-venv-process-environment-orig (cl-copy-list process-environment)) | `(let ((--with-venv-process-environment-orig (cl-copy-list process-environment)) | ||||
| (--with-venv-exec-path-orig (cl-copy-list exec-path))) | (--with-venv-exec-path-orig (cl-copy-list exec-path))) | ||||
| (unwind-protect | (unwind-protect | ||||
| (progn | (progn | ||||
| ;; Do the same thing that bin/activate does | |||||
| (setq exec-path | |||||
| (cons (concat ,dir "/bin") | |||||
| exec-path)) | |||||
| (setenv "VIRTUAL_ENV" ,dir) | |||||
| (setenv "PATH" (concat ,dir "/bin:" (or (getenv "PATH") ""))) | |||||
| (setenv "PYTHONHOME") | |||||
| (when dir | |||||
| ;; Do the same thing that bin/activate does | |||||
| (setq exec-path | |||||
| (cons (concat ,dir "/bin") | |||||
| exec-path)) | |||||
| (setenv "VIRTUAL_ENV" ,dir) | |||||
| (setenv "PATH" (concat ,dir "/bin:" (or (getenv "PATH") ""))) | |||||
| (setenv "PYTHONHOME")) | |||||
| ,@body) | ,@body) | ||||
| (setq process-environment | (setq process-environment | ||||
| --with-venv-process-environment-orig) | --with-venv-process-environment-orig) | ||||
| @@ -2042,25 +2046,37 @@ When nil, `with-venv' tries to find suitable venv dir.") | |||||
| (defmacro with-venv (&rest body) | (defmacro with-venv (&rest body) | ||||
| "Execute BODY with venv enabled. | "Execute BODY with venv enabled. | ||||
| This function tries to find suitable venv dir, or raise error when none found." | |||||
| This function tries to find suitable venv dir, or run BODY as usual when no | |||||
| suitable environment was found." | |||||
| `(with-venv-dir | `(with-venv-dir | ||||
| ;; If set explicitly use it | ;; If set explicitly use it | ||||
| ,(or with-venv-venv-dir | ,(or with-venv-venv-dir | ||||
| (with-venv-find-venv-dir)) | (with-venv-find-venv-dir)) | ||||
| ,@body)) | ,@body)) | ||||
| (defvar-local with-venv-previously-used nil | |||||
| "Previously used venv dir path.") | |||||
| (defun with-venv-find-venv-dir (&optional dir) | (defun with-venv-find-venv-dir (&optional dir) | ||||
| "Try to find venv dir for DIR or raise error when none found." | |||||
| "Try to find venv dir for DIR. | |||||
| If none found return nil." | |||||
| (with-temp-buffer | (with-temp-buffer | ||||
| (when dir | (when dir | ||||
| (cd dir)) | (cd dir)) | ||||
| (or | |||||
| ;; Check pipenv | |||||
| (with-venv--find-venv-dir-pipenv) | |||||
| ;; Check poetry | |||||
| (with-venv--find-venv-dir-poetry) | |||||
| ;; Search for .venv dir | |||||
| (with-venv--find-venv-dir-by-name)))) | |||||
| (let ((result (or | |||||
| ;; Check used previously | |||||
| (with-venv-check-exists | |||||
| with-venv-previously-used) | |||||
| ;; Check pipenv | |||||
| (with-venv-check-exists | |||||
| (with-venv--find-venv-dir-pipenv)) | |||||
| ;; Check poetry | |||||
| (with-venv-check-exists | |||||
| (with-venv--find-venv-dir-poetry)) | |||||
| ;; Search for .venv dir | |||||
| (with-venv-check-exists | |||||
| (with-venv--find-venv-dir-by-name))))) | |||||
| (setq with-venv-previously-used | |||||
| result)))) | |||||
| (defun with-venv--find-venv-dir-pipenv () | (defun with-venv--find-venv-dir-pipenv () | ||||
| "Try to find venv dir via pipenv." | "Try to find venv dir via pipenv." | ||||
| @@ -2087,9 +2103,17 @@ This function tries to find suitable venv dir, or raise error when none found." | |||||
| (let ((dir (locate-dominating-file default-directory | (let ((dir (locate-dominating-file default-directory | ||||
| ".venv"))) | ".venv"))) | ||||
| (when dir | (when dir | ||||
| ;; TODO: check with -check-exists | |||||
| (expand-file-name ".venv" | (expand-file-name ".venv" | ||||
| dir)))) | dir)))) | ||||
| (defun with-venv-check-exists (dir) | |||||
| "Return DIR as is if \"bin\" directory was found under DIR." | |||||
| (and dir | |||||
| (file-directory-p (expand-file-name "bin" | |||||
| dir)) | |||||
| dir)) | |||||
| ;; (with-venv (:dir default-directory) (message "a")) | ;; (with-venv (:dir default-directory) (message "a")) | ||||
| ;; (with-venv () (message "a")) | ;; (with-venv () (message "a")) | ||||