The Mastering Emacs ebook cover art

Emacs 28 Edition is out now!

Read a Free Sample

Learn More

Jedi: A completion library for Python

How to use Jedi, an advanced completion library for Python with a handy Emacs wrapper.

If you’re using Python with Emacs (using one of several competing, incompatible, and slightly different modes) you are used to a pretty… bare-bones experience: no completion; semi-functional dynamic docstring support; and little in the way of two-way communication between Python and Emacs.

NOTE: I recommend you use a Language Server Protocol (“LSP”) tool like Eglot or lsp-mode nowadays.

Enter Jedi, a completion library. Yes, Jedi, an editor-agnostic library that publishes auto completion, docstring support, and more. Excellent.

I’ve experimented with Pymacs – an interesting science project that adds “Python-like” support Emacs, so you can avoid interacting with Elisp, except not really – rope, and ropemacs and they were… disappointing. Slow, crash-prone, obtuse and impossible to extend. So I never really used them, and lived without completion or, well, much of anything beyond the REPL and my own handcrafted modifications.

The other alternative is the 600 lbs gorilla, CEDET, and its incomplete Python support, but that’s no good either.

Imagine my surprise, after fidgeting with the dependencies for both Jedi and Jedi.el, the Emacs library for Jedi, that it… works! And it’s good! It’s up-and-coming, I should say, but perfectly usable; it doesn’t get in my way, it’s got some crazy deferreds library it depends on for asynchronous, non-blocking querying of Jedi, but that bit works great – no input lag at all.

It seems to resolve, simplistically (which is good), as many assignments and method calls as one can reasonably expect from a non-evaluating, statically analyzing Python completion library.

Functioning Auto Complete in a Python buffer

The Jedi.el module also Just Works with the excellent auto-complete library, as you can see in the picture above.

Aside from completion, it also offers “find symbol definition at point” (a la TAGS, but not crap) and Jedi.el sensibly binds it to C-. by default. It also has a “related names” functionality, tracking down same-named identifiers in other modules; it uses Anything (now Helm) to display the results, and it is bound to C-c r. And finally, it can show the documentation for the identifier at point (be it a class or function) with C-c d. Useful.

I haven’t used Jedi and Jedi.el long enough to really get to know it, but I’m probably going to extend Jedi.el so it uses eldoc-mode for displaying the function parameters; it’s also a bit rough around the edges, and I may want to tweak certain things to my liking, but overall: huge success!

I highly recommend you give Jedi and Jedi.el a try!

Further Reading

Have you read my Reading Guide yet? It's a curated guide to most of my articles and I guarantee you'll learn something whether you're a beginner or an expert. And why not check out my book?

Subscribe to the Mastering Emacs newsletter

I write infrequently, so go on — sign up and receive an e-mail when I write new articles