Skip to content

Use pyenv within Emacs with the ability to use pyenv-version-alias and run pyenv-mode-hooks

Notifications You must be signed in to change notification settings

aiguofer/pyenv.el

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 

Repository files navigation

pyenv.el

Use pyenv to manage your Python versions within Emacs using pyenv. This is useful to make sure your code completion backend has the correct PYTHONPATH set up so auto-completion, jump to def, etc work as expected in each project. It can also display the current pyenv version running in the modeline as a reminder of the environment you're working in.

This repo was originally forked from pyenv.el, which was forked from rbenv.el.

This version has been changed quite a bit to support a variety of features:

  • Allow multiple pyenv versions enabled at once (just like pyenv)
  • Use a global pyenv mode
  • Only activate pyenv mode by setting PYENV_VERSION environment variable
  • Allow easy customization of modeline text
  • Support use of pyenv-version-alias
  • Make it easy to auto-switch pyenv when switching between buffers
  • Allow hooks to run when pyenv changes

Why not pyenv-mode?

  • Aside from setting the environment variable, pyenv-mode also sets the python-shell-virtualenv-root which doesn't make much sense in the context of using pyenv, since pyenv enables using multiple versions at once as well as using non-virtualenv versions. It would be though to change that design.
  • pyenv-mode depends on pythonic, and to get something resembling global-mode you also need pyenv-mode-auto.
  • I forked this a long time ago to enable using multiple versions at once like pyenv. It was easier to continue modifying this than try to re-architect and hope my PRs get accepted with pyenv-mode

Installation

Clone this repo into a directory and:

(add-to-list 'load-path (expand-file-name "/path/to/pyenv.el/"))
(require 'pyenv)
(global-pyenv-mode)

Alternatively, use straight.el:

(use-package pyenv
  :straight (:host github :repo "aiguofer/pyenv.el")
  :config
  (global-pyenv-mode))

Usage

  • global-pyenv-mode activate / deactivate pyenv.el (The current Python version is shown in the modeline)
  • pyenv-use-global will activate your global python
  • pyenv-use allows you to choose what python version you want to use
  • pyenv-use-corresponding searches for .python-version and activates the corresponding python

Configuration

pyenv installation directory

By default pyenv.el assumes that you installed pyenv into ~/.pyenv. If you use a different installation location you can customize pyenv.el to search in the right place:

(setq pyenv-installation-dir "/usr/local/pyenv")

IMPORTANT:: Currently you need to set this variable before you load pyenv.el

the modeline

pyenv.el will show you the active python in the modeline. If you don't like this feature you can disable it:

(setq pyenv-show-active-python-in-modeline nil)

The default modeline representation is the python version (colored red) in square brackets. You can change the format by customizing the variable:

;; this will remove the colors
(setq pyenv-modeline-function 'pyenv--modeline-plain)

You can also define your own function to format the python version as you like.

You can also configure the pre/post-fix if you don't like the square brackets, for example, to set the prefix to the python glyph using Nerd Fonts:

(setq pyenv-modestring-prefix "")
(setq pyenv-modestring-postfix nil)

pyenv-version-alias

If using pyenv-version-alias, you can enable it with:

(setq pyenv-use-alias 't)

auto-update pyenv when switching buffers

In order to automatically switch to the corresponding pyenv when switching between Python buffers, you can use switch-buffer-functions and set it up like this (note I only update when changing to a Python buffer):

(use-package switch-buffer-functions
  :straight t
  :config
  (defun pyenv-update-on-buffer-switch (prev curr)
    (if (string-equal "Python" (format-mode-line mode-name nil nil curr))
        (pyenv-use-corresponding)))

  (add-hook 'switch-buffer-functions 'pyenv-update-on-buffer-switch))

always using the right Jupyter console

If you have a jupyter kernel per pyenv version installed onto a "global" jupyter install (for example, using pyenv-jupyter-kernel), you could make sure all your shell related commands (python-shell-send-buffer/region) work on the right (currently active) kernel using:

(setq python-shell-interpreter "jupyter-console"
      python-shell-interpreter-args "--simple-prompt"
      python-shell-prompt-detect-failure-warning nil)

(add-to-list 'python-shell-completion-native-disabled-interpreters
             "jupyter-console")

(defun my-setup-python (orig-fun &rest args)
  "Use corresponding kernel"
  (let* ((curr-python (car (split-string (pyenv/version-name) ":")))
         (python-shell-buffer-name (concat "Python-" curr-python))
         (python-shell-interpreter-args (concat "--simple-prompt --kernel=" curr-python)))
    (apply orig-fun args)))

(advice-add 'python-shell-get-process-name :around #'my-setup-python)

ensure PATH is set correctly

By default, pyenv.el will set up the PATH to make sure the necessary pyenv directories ($PYENV_ROOT/{bin,shims}) are in your PATH. If Emacs has already inherited the correct PATH, you can disable this behavior by setting:

(setq pyenv-set-path nil)

Note: this needs to be before you call (global-pyenv-mode)

Running hooks on pyenv switch

You can use pyenv-mode-hook to do things when you change your pyenv. This can be useful for updating code completion backends. For example, you could run elpy-rpc-restart when you switch pyenv versions like so:

(add-hook 'pyenv-mode-hook 'elpy-rpc-restart)

About

Use pyenv within Emacs with the ability to use pyenv-version-alias and run pyenv-mode-hooks

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published