Improve python venv handling

This commit is contained in:
Jeremy Dormitzer 2020-04-28 12:52:41 -04:00
parent 707b20eeff
commit 02d97f2b2f

View File

@ -2820,8 +2820,8 @@ Emacs support for the Language Server Protocol
#+END_SRC #+END_SRC
* Python * Python
** General
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
;; (leader-def-key "sp" #'elpy-shell-switch-to-shell)
(leader-def-key "sp" #'run-python) (leader-def-key "sp" #'run-python)
(add-hook 'python-mode-hook #'disable-tab-insert) (add-hook 'python-mode-hook #'disable-tab-insert)
#+END_SRC #+END_SRC
@ -2845,37 +2845,6 @@ Font-lock for f-strings:
(0 font-lock-variable-name-face t))))))) (0 font-lock-variable-name-face t)))))))
#+END_SRC #+END_SRC
Elpy is a python IDE package:
#+BEGIN_SRC emacs-lisp :tangle no
(use-package elpy
:init (elpy-enable)
:config (setq elpy-rpc-python-command "python3"))
#+END_SRC
Alternatively, use the LSP python client:
#+BEGIN_SRC emacs-lisp
(add-hook 'python-mode-hook #'lsp-deferred)
(general-def 'normal python-mode-map "C-c C-d" #'lsp-describe-thing-at-point)
#+END_SRC
Support pyvenv within Emacs:
#+BEGIN_SRC emacs-lisp
(use-package pyvenv
:commands (pyvenv-mode pyvenv-workon pyvenv-activate)
:init
(add-hook 'after-init-hook #'pyvenv-mode))
(defun eshell/workon (name)
(pyvenv-workon name))
(defun eshell/activate (dir)
(pyvenv-activate dir))
(defun eshell/deactivate ()
(pyvenv-deactivate))
#+END_SRC
ISort is a Python utility to sort imports: ISort is a Python utility to sort imports:
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package py-isort (use-package py-isort
@ -2886,24 +2855,6 @@ ISort is a Python utility to sort imports:
(python-mode-map "C-c C-i" #'py-isort-buffer)) (python-mode-map "C-c C-i" #'py-isort-buffer))
#+END_SRC #+END_SRC
Pipenv is the Python standard dependency management/virtual environment tool. pipenv.el teaches Emacs its ways:
#+BEGIN_SRC emacs-lisp
(use-package pipenv
:hook (python-mode . pipenv-mode)
:commands (pipenv-mode
pipenv-activate
pipenv-run))
#+END_SRC
A function to run a pipenv-aware python repl:
#+BEGIN_SRC emacs-lisp
(defun run-pipenv ()
"Runs a pipenv-aware Python shell"
(interactive)
(pipenv-activate)
(run-python nil nil t))
#+END_SRC
Run black on the current buffer: Run black on the current buffer:
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(general-def 'normal python-mode-map "C-M-\\" #'format-all-buffer) (general-def 'normal python-mode-map "C-M-\\" #'format-all-buffer)
@ -2915,12 +2866,126 @@ Run black on the current buffer:
:hook ((python-mode . sphinx-doc-mode))) :hook ((python-mode . sphinx-doc-mode)))
#+END_SRC #+END_SRC
** Dev environment/IDE stuff
Support pyvenv within Emacs:
#+BEGIN_SRC emacs-lisp
(use-package pyvenv
:commands (pyvenv-mode
pyvenv-workon
pyvenv-activate
pyvenv-track-virtualenv))
(defun eshell/workon (name)
(pyvenv-workon name))
(defun eshell/activate (dir)
(pyvenv-activate dir))
(defun eshell/deactivate ()
(pyvenv-deactivate))
#+END_SRC
Pipenv is a dependency management/virtual environment tool. pipenv.el teaches Emacs its ways:
#+BEGIN_SRC emacs-lisp
(use-package pipenv
:commands (pipenv-mode
pipenv-activate
pipenv-run)
:custom
(pipenv-with-projectile nil)
(pipenv-with-flycheck nil))
#+END_SRC
And support pyenv (NOT pyvenv) to change Python versions: And support pyenv (NOT pyvenv) to change Python versions:
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package pyenv-mode (use-package pyenv-mode
:defer t) :defer t)
#+END_SRC #+END_SRC
Add a hook to set the correct python for the current buffer:
#+BEGIN_SRC emacs-lisp
(defvar python-buffer-venv nil)
(make-variable-buffer-local 'python-buffer-venv)
(defun save-buffer-venv (&rest args)
(setq python-buffer-venv pyvenv-virtual-env))
(advice-add 'pyvenv-activate :after #'save-buffer-venv)
(advice-add 'pyvenv-workon :after #'save-buffer-venv)
(advice-add 'pyvenv-track-virtualenv :after #'save-buffer-venv)
(defun activate-buffer-venv ()
"Activates the virtualenv that was previously set in this buffer."
(when (and python-buffer-venv
(not (eq python-buffer-venv pyvenv-virtual-env)))
(pyvenv-activate python-buffer-venv)))
(defun maybe-activate-venv ()
"Activates the virtual env for the current buffer if one exists.
Returns `t' if a venv was activated."
(interactive)
(cond
((pipenv-activate) t)
((or pyvenv-activate pyvenv-workon)
(progn (pyvenv-track-virtualenv) t))))
(defun activate-venv-post-command ()
(ignore-errors (activate-buffer-venv)))
(define-minor-mode python-env-mode
"Global minor mode to track Python environment."
:global t
(cond
(python-env-mode
(add-to-list 'mode-line-misc-info '(python-env-mode pyvenv-mode-line-indicator))
(add-hook 'hack-local-variables-hook #'maybe-activate-venv)
(add-hook 'post-command-hook #'activate-venv-post-command))
((not python-env-mode)
(setq mode-line-misc-info (delete '(python-env-mode pyvenv-mode-line-indicator)
mode-line-misc-info))
(remove-hook 'hack-local-variable-hook #'maybe-activate-venv)
(remove-hook 'post-command-hook #'activate-venv-post-command))))
(add-hook 'after-init-hook #'python-env-mode)
#+END_SRC
Use the LSP python client:
#+BEGIN_SRC emacs-lisp
(defun python-lsp ()
"Activates the project virtualenv if one exists then runs LSP."
(interactive)
(maybe-activate-venv)
(lsp-deferred))
(add-hook 'python-mode-hook #'python-lsp)
(general-def 'normal python-mode-map "C-c C-d" #'lsp-describe-thing-at-point)
#+END_SRC
Fix the doom-modeline Python display for Pipenv projects:
#+BEGIN_SRC emacs-lisp
(with-eval-after-load 'doom-modeline-env
(doom-modeline-def-env python
:hooks 'python-mode-hook
:command (lambda ()
(let ((old (getenv "PIPENV_VERBOSITY")))
(setenv "PIPENV_VERBOSITY" "-1")
(cond ((and (fboundp 'pipenv-project-p)
(pipenv-project-p))
(list "pipenv" "run"
(or doom-modeline-env-python-executable
python-shell-interpreter
"python")
"--version"))
((list (or doom-modeline-env-python-executable
python-shell-interpreter
"python")
"--version")))
(setenv "PIPENV_VERBOSITY" old)))
:parser (lambda (line) (cadr (split-string line)))))
#+END_SRC
** Autoflake ** Autoflake
[[https://pypi.org/project/autoflake/][Autoflake]] is a tool that removes unused imports and variables from Python code: [[https://pypi.org/project/autoflake/][Autoflake]] is a tool that removes unused imports and variables from Python code:
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp