lang/python: rewrite modeline version segment

+ Add $PYENV_ROOT/shims was added to exec-path, so pyenv python version
  is picked up on.
+ Fixes out-of-date python version in the modeline of other buffers
  after switching pyenv/pyvenv/conda envs.
+ The pipenv version and regular python display have been merged.
This commit is contained in:
Henrik Lissner 2018-09-25 22:17:41 -04:00
parent 8afbb804d9
commit b91a8f0d2f
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
2 changed files with 53 additions and 32 deletions

View file

@ -1,11 +1,18 @@
;;; lang/python/autoload/python.el -*- lexical-binding: t; -*-
(defvar +python-version-cache (make-hash-table :test 'equal)
"TODO")
;;;###autoload
(defun +python/repl ()
"Open the Python REPL."
(interactive)
(process-buffer (run-python nil t t)))
(defun +python--extract-version (prefix str)
(when str
(format "%s%s" prefix (cadr (split-string str " ")))))
;;;###autoload
(defun +python-version ()
"Return the currently installed version of python on your system or active in
@ -14,18 +21,37 @@ the current pipenv.
This is not necessarily aware of env management tools like virtualenv, pyenv or
pipenv, unless those tools have modified the PATH that Emacs picked up when you
started it."
(let* ((pipenv-dir (pipenv-project-p))
(default-directory (or pipenv-dir default-directory))
(command (if pipenv-dir
"pipenv run python --version"
"python --version"))
(bin (car (split-string command " "))))
(unless (executable-find bin)
(user-error "Couldn't find %s executable in PATH" bin))
(with-temp-buffer
(let ((p (apply #'call-process bin nil (current-buffer) nil
(cdr (split-string command " " t))))
(output (string-trim (buffer-string))))
(unless (zerop p)
(user-error "'%s' failed: %s" command output))
(cadr (split-string output " " t))))))
(condition-case _
(if-let* ((proot (and (fboundp 'pipenv-project-p)
(pipenv-project-p))))
(let* ((default-directory proot)
(v (car (process-lines "pipenv" "run" "python" "--version"))))
(puthash proot
(+python--extract-version "Pipenv " v)
+python-version-cache))
(puthash (doom-project-root)
(+python--extract-version "Python " (car (process-lines "python" "--version")))
+python-version-cache))
(error "Python")))
;;
;; Hooks
;;;###autoload
(defun +python|update-version (&rest _)
"Update `+python--version' by consulting `+python-version' function."
(setq +python--version
(or (gethash (or (and (fboundp 'pipenv-project-p)
(pipenv-project-p))
(doom-project-root))
+python-version-cache)
(+python-version))))
;;;###autoload
(defun +python|update-version-in-all-buffers ()
"Update `+python-version' in all buffers in `python-mode'."
(dolist (buffer (doom-buffers-in-mode 'python-mode))
(setq +python-version-cache (clrhash +python-version-cache))
(with-current-buffer buffer
(+python|update-version))))

View file

@ -1,10 +1,9 @@
;;; lang/python/config.el -*- lexical-binding: t; -*-
(defvar +python-mode-line-indicator
'("Python" (+python-version (" " +python-version)))
(defconst +python-mode-line-indicator '("" +python--version)
"Format for the python version/env indicator in the mode-line.")
(defvar-local +python-version nil
(defvar-local +python--version nil
"The python version in the current buffer.")
@ -64,9 +63,6 @@
(setq mode-name +python-mode-line-indicator))
(add-hook 'python-mode-hook #'+python|adjust-mode-line)
(defun +python|update-version (&rest _)
(setq +python-version (+python-version)))
(+python|update-version)
(add-hook 'python-mode-hook #'+python|update-version))
@ -135,8 +131,8 @@
:hook (python-mode . pipenv-mode)
:init (setq pipenv-with-projectile nil)
:config
(advice-add #'pipenv-activate :after-while #'+python|update-version)
(advice-add #'pipenv-deactivate :after-while #'+python|update-version))
(advice-add #'pipenv-activate :after-while #'+python|update-version-in-all-buffers)
(advice-add #'pipenv-deactivate :after-while #'+python|update-version-in-all-buffers))
(def-package! pyenv-mode
@ -144,11 +140,10 @@
:after python
:config
(pyenv-mode +1)
(advice-add #'pyenv-mode-set :after #'+python|update-version)
(advice-add #'pyenv-mode-unset :after #'+python|update-version)
(add-to-list '+python-mode-line-indicator
'(:eval (if (pyenv-mode-version) (concat " pyenv:" (pyenv-mode-version))))
'append))
(when (executable-find "pyenv")
(add-to-list 'exec-path (expand-file-name "shims" (or (getenv "PYENV_ROOT") "~/.pyenv"))))
(advice-add #'pyenv-mode-set :after #'+python|update-version-in-all-buffers)
(advice-add #'pyenv-mode-unset :after #'+python|update-version-in-all-buffers))
(def-package! pyvenv
@ -156,8 +151,8 @@
:after python
:config
(defun +python-current-pyvenv () pyvenv-virtual-env-name)
(add-hook 'pyvenv-post-activate-hooks #'+python|update-version)
(add-hook 'pyvenv-post-deactivate-hooks #'+python|update-version)
(add-hook 'pyvenv-post-activate-hooks #'+python|update-version-in-all-buffers)
(add-hook 'pyvenv-post-deactivate-hooks #'+python|update-version-in-all-buffers)
(add-to-list '+python-mode-line-indicator
'(pyvenv-virtual-env-name (" venv:" pyvenv-virtual-env-name))
'append))
@ -192,8 +187,8 @@
(conda-env-initialize-interactive-shells)
(after! eshell (conda-env-initialize-eshell))
(add-hook 'conda-postactivate-hook #'+python|update-version)
(add-hook 'conda-postdeactivate-hook #'+python|update-version)
(add-hook 'conda-postactivate-hook #'+python|update-version-in-all-buffers)
(add-hook 'conda-postdeactivate-hook #'+python|update-version-in-all-buffers)
(add-to-list '+python-mode-line-indicator
'(conda-env-current-name (" conda:" conda-env-current-name))
'append))