Self-hosted service
pythonic-emacs/anaconda-mode avatar
pythonic-emacs/anaconda-mode

anaconda-mode: Python completion, navigation and docs inside Emacs

Code navigation, documentation lookup and completion for Python.

709 stars88 forksEmacs LispGPL-3.0

At a glance

What is it?
anaconda-mode gives Emacs the code navigation and documentation lookup a Python developer expects, with completion, jump to definition, find references and virtual environment support, and it keeps working over Tramp, Vagrant and Docker by talking to an interpreter on the other machine. The mode is distributed through MELPA, and it drives a real Python process rather than parsing the file itself.
Who is it for?
anaconda-mode is worth setting up if you live in Emacs and write Python, because the alternative for most people is an editor with its own Python plugin, and here the analysis comes from a real interpreter so the results match what the code will actually do, including inside containers and on remote hosts.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 126 days ago.
What is it written in?
Mainly Emacs Lisp, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Completion and navigation driven by a real Python interpreter

anaconda-mode is described as providing code navigation, documentation lookup and completion for Python, and the feature list is short enough to state plainly: context-sensitive code completion, jump to definitions, find references, view documentation, virtual environment support, eldoc mode, and all of it inside vagrant, docker and remote hosts.

What makes those features work is that the answers come from a running Python process rather than from parsing the file in the editor. That distinction shows up in the interaction model. The interactive command list is dominated by prefix arguments that mean show me this in a different place, which only makes sense if the search happens elsewhere and the results are then displayed: find definitions, find definitions in another window, find definitions in another frame, and the same trio for assignments and for references. The xref-pop-marker-stack command then lets you walk back through the places you have been.

When multiple candidates are found for definitions, assignments or usages, you get an advanced anaconda navigator buffer rather than a list in the echo area, which is a reasonable choice for a search that can return hundreds of hits.

Completion is bound to C-M-i, which the README is careful to note is the standard Emacs binding for the complete-at-point function, so the key does not surprise you if you have used it elsewhere. It also points out that company-mode can be used with the company-anaconda backend to get a more capable user interface, which is the usual pairing in modern Emacs setups.

The mode is written in Emacs Lisp, distributed through MELPA and MELPA Stable, and the repository is licensed under GPL-3.0.

Enabling it and adding eldoc on top

Installation is one Melpa command, and the setup is two lines of Lisp.

The Melpa route is the package-install interactive command, which pulls the package from the Melpa archive. The manual route is to clone the repository somewhere and add that directory to your load-path, which is the approach to take if you want to run a working copy.

The mode is also bundled in two well known Emacs distributions, which is worth knowing before you install anything. It is included in the Prelude distribution, where the prelude-python module has the details, and in Spacemacs, where the python language layer covers it. If you use either, enabling the mode is a configuration change rather than an installation.

Turning it on for every Python buffer is a hook:

lisp
(add-hook 'python-mode-hook 'anaconda-mode)

Then there is the eldoc integration, which is a separate mode. The anaconda-eldoc-mode provides a documentation function to eldoc-mode, so when your point is between the parentheses of a function call, its parameters are shown in the echo area. You enable it in addition to the previous setup:

lisp
(add-hook 'python-mode-hook 'anaconda-eldoc-mode)

The reason it is a separate hook rather than part of anaconda-mode is worth noting. eldoc-mode is a general facility in Emacs for showing the signature of a function at point, and it is used by many language modes. Rather than bundling its own version, anaconda-mode provides the backend for it, so you get the standard eldoc behaviour with Python-aware information.

The two hooks together mean that in a Python buffer you have completion, definition jumping, reference finding and inline signature display, which is most of what an IDE would give you for the same file.

The interpreter has to be able to import your project

The point that decides whether anaconda-mode works at all is that the search happens inside a Python process, and that process has to be able to see your code.

The PYTHONPATH section explains the mechanism. You add your project to the Emacs PYTHONPATH, and if you store project dependencies somewhere on your machine you can add them as well:

lisp
(add-to-list 'python-shell-extra-pythonpaths "/path/to/the/project")
(add-to-list 'python-shell-extra-pythonpaths "/path/to/the/dependency")

The virtual environment section then tells you the better way to do the same thing. The recommendation is to use a virtual environment to isolate your project dependencies from others on the system, and to install your project in editable mode inside that environment, and the stated reason is that this improves search functionality. Then you activate the environment inside Emacs with the pythonic-activate interactive command, giving it the path to the virtualenv.

The editable install detail is the important one. An editable install puts a path entry into the environment rather than copying the package into site-packages, which is what makes the interpreter able to import your working copy. Without it, the interpreter can only see a snapshot of the code, and completion will offer names from the installed version rather than the file you are editing.

The activation is not a global switch. Each action applies to anaconda-mode immediately, and the next anaconda-mode command you call uses that environment for search and completion candidates. The README also points at pyenv-mode as a package to hold virtual environments in their actual state, which is the pragmatic choice for people who switch between projects often.

A related constraint appears in the remote section. All kinds of searching from inside the virtual environment are available from any buffer, however searching inside your project is available only if you open it on the same machine as the interpreter. That is a direct consequence of how the search works, and it is the sort of thing that surprises people who expect a remote buffer to behave exactly like a local one.

Tramp, Vagrant and Docker, and the one thing that does not work

The remote support is the part of anaconda-mode that no editor plugin matches, because the analysis runs wherever the interpreter is.

Over Tramp it is straightforward. You connect to the remote server using tramp, and anaconda-mode can search for completion candidates and everything else on the remote server while you run Emacs locally. You open a remote file, and once tramp has connected and you can see the buffer content, completion and definition search work as usual. You can even use a virtual environment from the remote host, by giving pythonic-activate a remote path.

There is one rule that catches people out, and the README states it plainly: the remote host must be a real host name or an IP address, and SSH aliases are not allowed to be used with anaconda-mode. The reason is implicit in the design, since the mode has to address the interpreter and an alias is a local convenience that does not resolve on the far side.

Vagrant works the same way with a port number in the file name:

text
    C-x C-f /ssh:vagrant@localhost#2222:/vagrant/polls/views.py

The README also gives the authentication tip, which is to copy your public ssh key to the vagrant box with ssh-copy-id, so the editor does not stop for a password prompt. And you can activate a virtual environment that lives inside the box by giving pythonic-activate the same remote path form.

Docker needs two extra dependencies, docker-tramp for the Emacs side and the socat utility, and your containers need to be up and running. You then point the interpreter at the one inside the container and open the file through the docker tramp prefix. The interpreter setting is a plain Lisp assignment:

lisp
(setq python-shell-interpreter "/usr/local/bin/python")

The same variable is how you point at a different remote interpreter, which is the general escape hatch when the default path is wrong for a given setup.

The packaging is plain Emacs Lisp with Cask and Eask for the build

The repository is small and conventional for a mature Emacs package. The top-level entries are anaconda-mode.el for the mode itself, anaconda-mode.py which is the Python side that the mode talks to, a Cask file and an Eask file, a Makefile, a scripts/ directory, static/ for the images, a README.markdown and the LICENSE file.

The Cask and Eask split is the part worth understanding if you want to work on the package. Cask is the dependency manager, and the Eask file is the build system that produces the package, compiles the byte-compiled Lisp and installs the result. The Makefile wraps both:

text
emacs:
	cask emacs -Q -l scripts/init.el simple.py

The emacs target starts a clean Emacs with no configuration, loads the project's init script and opens a simple.py file, which is the fastest way to get a working development loop. The install and update targets handle dependencies, and the ci target runs the whole sequence:

text
ci:
	eask clean all
	eask package
	eask install
	eask compile

Clean, package, install and compile in that order, with the clean first so a stale build does not contaminate the result.

The CI badge in the README points at a GitHub Actions workflow for tests, and the .github/ directory holds it. The last push was on 2026-06-19 and the repository is not archived, so the mode is still being worked on.

On the Python side, the supported versions are listed as 2.7 and 3.4 through 3.13. That range is broad, and the 2.7 entry reflects the age of the package rather than a claim that anyone runs 2.7 today, but the upper end of the range is the thing to check, since a Python version newer than the mode knows about is where surprises come from.

Editorial conclusion

anaconda-mode is worth setting up if you live in Emacs and write Python, because the alternative for most people is an editor with its own Python plugin, and here the analysis comes from a real interpreter so the results match what the code will actually do, including inside containers and on remote hosts. It is the wrong tool if you only want a linter, since that is a different class of tool, and it is the wrong tool if you cannot run a Python process, because the mode's answers come from introspection rather than from static parsing. Before you configure it, verify three things yourself: that the Python version you point it at is one the mode supports, since the list runs from 2.7 through 3.13, that your project is importable from the interpreter you activate, because the mode searches what the interpreter can import, and that the remote host name is a real host or IP rather than an SSH alias, since the README is explicit that aliases do not work with anaconda-mode.

Frequently asked questions

What does anaconda-mode provide for Python in Emacs?

It provides context-sensitive code completion, jump to definitions, find references, documentation viewing, virtual environment support and eldoc mode, and all of it works inside vagrant, docker and remote hosts. The interactive commands include find definitions, find assignments and find references, each with variants that show results in another window or frame.

How do I install and enable anaconda-mode?

Install it from Melpa with the package-install command, or clone the repository and add it to your load-path, and enable it in Python buffers with (add-hook 'python-mode-hook 'anaconda-mode). The mode is also bundled in the Prelude and Spacemacs distributions.

How do I use a virtual environment with anaconda-mode?

Install your project in editable mode inside the virtual environment so the interpreter can import your working copy, then activate it with the pythonic-activate command giving the path to the environment. The activation applies immediately and the next anaconda-mode command uses that environment for search and completion.

Can anaconda-mode work on a remote host or inside a container?

Yes. Over Tramp you open a remote file and completion and definition search run on the remote server while Emacs stays local, and you can activate a remote virtual environment. Docker needs the docker-tramp package and the socat utility, and you point python-shell-interpreter at the interpreter inside the container.

Why does anaconda-mode not work with my SSH aliases?

The README states that the remote host must be a real host name or an IP address and that SSH aliases are not allowed with anaconda-mode, because the mode has to reach the interpreter and an alias is a local shortcut that does not resolve on the far side.

Official sources

  1. Issues
  2. License: GPL-3.0
  3. pythonic-emacs/anaconda-mode on GitHub
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/pythonic-emacs-anaconda-mode.svg)](https://hysenlabs.com/projects/pythonic-emacs-anaconda-mode)

Was this useful?