/conda.el

Emacs helper library (and minor mode) to work with conda environments

Primary LanguageEmacs Lisp

conda.el

Emacs library for working with conda environments, largely ported from virtualenvwrapper.el.

MELPA

what it does

  • Makes Python shells, interactive shells, eshell, anaconda-mode, and so on aware of your conda environments
  • Detects and auto-activates the right conda environment for a particular buffer.

basic usage

  • Install conda (included if you have installed Anaconda or Miniconda)

  • Install from MELPA (M-x package-install conda), or just put conda.el on your load path.

  • Add it to your configuration (e.g. your .emacs or init.el). Something like this should work:

    (require 'conda)
    ;; if you want interactive shell support, include:
    (conda-env-initialize-interactive-shells)
    ;; if you want eshell support, include:
    (conda-env-initialize-eshell)
    ;; if you want auto-activation (see below for details), include:
    (conda-env-autoactivate-mode t)
  • If your Anaconda installation is anywhere other than the default (~/.anaconda3) then set the conda-anaconda-home custom variable to the installation path. For instance, in my configuration I have:

    (custom-set-variables
     '(conda-anaconda-home "/path/to/my/Anaconda"))
  • Use M-x conda-env-activate to activate conda environments and M-x conda-env-deactivate to deactivate them. You can also use M-x conda-env-activate-for-buffer to try and detect the correct conda environment for a buffer, or use the conda-env-autoactivate-mode minor mode to do this automatically (see below for more details).

what do activating and deactivating actually do?

As with virtualenvwrapper.el, activating a conda environment does:

  1. Sets python-shell-virtualenv-path to the environment's directory so that when you open a new python shell, it is aware of the environment's installed packages and modules.
  2. The environment's bin directory is prepended to the PATH environment variable and Emacs' internal exec-path, so that when a process is launched from Emacs it is aware of any executables installed in the virtualenv (e.g py.test, pep8, etc.). This comes in handy for FlyCheck to correctly lint your code, or to use M-! nosetests to run your tests, and so on.
  3. The VIRTUAL_ENV environment variable is set to the environment's directory so any tools that depend on this variable function correctly (such as jedi).
  4. pythonic-activate is called on the environment to ensure any other Python- related code is initialized with the right working path, version of Python, and so on.

When you deactivate, all these things are undone. You can safely modify your PATH and exec-path while a virtualenv is active and expect the changes not to be destroyed.

This covers everything except interactive shells, which are covered in the next section.

shells

This thing supports two types of interactive shells, the eshell and the interactive subshell (what you get when you do M-x shell).

interactive shell

Support for interactive shell is turned on by calling conda-env-initialize-interactive-shell. After this is done, whenever you call shell, the shell will start in the correct conda environment. Note that changing the environment in Emacs will not affect any running shells and vice-versa; they are independent processes.

WARNINGS

This feature is a pretty big hack and works by advising the shell function. This works fine if you haven't otherwise tricked out or advised it, but if this is the case it may break.

eshell

Support for eshell is turned on by calling conda-env-initialize-eshell. After doing this, any new eshells you launch will be in the correct environment and have access to installed executables, etc. The mode also provides a variety of virtualenvwrapper-like commands that work identically to their bash/zsh counterparts (described in detail below). Note that in contrast to how interactive shells work, Eshell shares an environment with Emacs, so if you activate or deactivate in one, the other is affected as well. Note that this requires the variable eshell-modify-global-environment to be set to true -- running conda-env-initialize-eshell causes this to occur.

command reference

The commands this mode provides are prefixed with conda- (right now, the majority start with conda-env- since they deal with environments). All commands can be called interactively using M-x. Many of these commands have also been aliased without prefixes as eshell functions, so you can call them on the eshell just as you would in bash or zsh. For example:

eshell> activate myenv
eshell> deactivate

All will do what would expect.

conda-env-activate

Prompts for the name of a conda environment and activates it as described above. Can also be called noninteractively as (conda-env-activate "<NAME>").

conda-env-deactivate

Deactivates the current conda environment, undoing everything that conda-env-activate did. This can also be called noninteractively as (conda-env-deactivate).

conda-env-list

List all available conda environments, in a temp buffer.

useful macros

There is a conda-with-env macro, which takes the name of a conda environment and then any number of forms and executes those forms with that environment active.

Since it's common to want to execute shell commands, there is a convenience macro conda-with-env-shell-command, which takes a string, interpreted as a shell command, and do exactly what you'd expect. So for example, you can do (conda-with-env-shell-command "myenv" "conda install pep8") to install pep8 in the myenv conda environment. It can also be called interactively and will prompt for a command to run if so.

keybindings

Just like virtualenvwrapper.el, no keybindings defined here. Do what you like!

automatically activating a virtualenv in a particular project

It's also common to want to have an environment automatically activated when you open a file in a certain project. This can be done with the conda-env-autoactivate-mode minor mode, which will: - check for a per-directory local variable setting the conda-project-env-name - search up the directory tree for a file defining a conda environment, such as an environment.yml file, and try to activate the named environment

displaying the currently active environment on the mode line

The name of the currently active conda environment is stored in the variable conda-env-current-name. If you want to have it displayed on your customized mode line you can just add (:exec (list conda-env-current-name))) somewhere in your mode-line-format. If you don't customize your mode line and just want to have the current virtualenv displayed, you can do:

(setq-default mode-line-format (cons '(:exec conda-env-current-name) mode-line-format))

eshell prompt customization

You might also want to have the name of your current conda environment appear on the eshell prompt. You can do this by a pretty similar mechanism, just include conda-env-current-name in your eshell-prompt-function somewhere.

More about customizing the eshell prompt on the EmacsWiki.

bugs / comments / contributions

Please open an issue or a PR! I'm happy to pull in contributions or take suggestions for improvements.

license (the MIT license)

Copyright (C) 2016 Rami Chowdhury

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.