30

What is the easiest way to configure Emacs to be able to look up where a function is defined? I want to highlight it in Emacs and press a key combo to look up where the source of the function is.

Can you also find out where a specific function is being used?

This is easily done in PyCharm, but can it also be easily done in Emacs?

nanny
  • 5,704
  • 18
  • 38
Low Kian Seong
  • 413
  • 1
  • 4
  • 6

10 Answers10

18

Did you try Elpy? It binds elpy-goto-definition to the key M-..
If you have a recent Emacs, I think you can also jump back with xref-pop-marker-stack (M-,). Elpy has some other nice features as well.

To install it, follow the instructions in the link.

bmag
  • 1,703
  • 10
  • 12
12

I use Jedi mode for Python and I'm very happy with it. Not only does it do accurate look ups for function calls, it resolves functions to the correct definition even in complicated situations (like inheritance). Comes with auto complete to boot. http://tkf.github.io/emacs-jedi/latest/

10

The feature of PyCharm that you mention was one of my favourites, and one of the first things I looked for in trying to replace PyCharm completely with Emacs (which I am happy to say I have been able to do).

As mentioned in another answer the elpy package has this feature (in addition to many other useful IDE features). However, if you use elpy-goto-definition to look up the symbol at point, you will find sooner or later that in some cases where PyCharm would succeed in finding what you are looking for, elpy will not. As the docs say:

the backends can not always identify what kind of symbol is at point. Especially after a few indirections, they have basically no hope of guessing right, so they don’t

In this case, invoking elpy-goto-definition will do nothing and show a little error message in the echo area. When this happens, of course you still want to find what you are looking for, and elpy doesn't leave you hanging. In this kind of situation I always use C-c C-s (elpy-rgrep-symbol) to rgrep for the symbol at point in whatever project I am in. At least for me, the thing I am looking for more or less always shows up in the rgrep results. Actually, I think this is similar to what PyCharm does too: if you try to look up the definition of something and PyCharm is not sure where it is defined, it will have you choose from a list. I actually prefer elpy's implementation, because rather than a transient list that disappears when you go to the first option, elpy-rgrep-symbol will leave the list of possibilities open in another buffer so that you can jump back and forth between them if necessary.

Since my workflow is almost always to first call elpy-goto-definition and if it fails, call elpy-rgrep-symbol, I decided to hack together a simple function that just calls elpy-rgrep-symbol automatically if elpy-goto-definition fails. That function is below:

(defun goto-def-or-rgrep ()
  "Go to definition of thing at point or do an rgrep in project if that fails"
  (interactive)
  (condition-case nil (elpy-goto-definition)
    (error (elpy-rgrep-symbol (thing-at-point 'symbol)))))

Then I bind this to M-. (the default binding for elpy-goto-definition).

(define-key elpy-mode-map (kbd "M-.") 'goto-def-or-rgrep)

This way I can use one of my favorite PyCharm features in my favorite editor. I know this is kind of an old question and you may have already solved this problem or moved on, but I hope you or someone else finds this useful!

elethan
  • 4,755
  • 3
  • 29
  • 56
3

python-mode.el provides a command py-find-definition - see in menu Help.

Andreas Röhler
  • 1,894
  • 10
  • 10
  • 6
    Note that python-mode.el has to be installed. It is not the `python-mode` that Emacs has by default. (http://stackoverflow.com/questions/11363089/how-to-install-python-mode-el-for-emacs) – Brian Z Mar 13 '15 at 09:46
  • 1
    `py-find-definition` does not show up – alper Feb 29 '20 at 17:44
2

M-. works in anaconda-mode (which I switched to after having problems with elpy).

Note that you need proper python environment, in my case I do the following:

  • mkvirtualenv someenv
  • python setup.py develop for all modules develop or use (or prefer to reach source instead of installed version)
  • M-x venv-workon RET someenv to enable paths in Emacs.

Then I configure anaconda-mode to be active whenever I edit python and voila, M-. works

Stefan
  • 26,154
  • 3
  • 46
  • 84
Mekk
  • 1,017
  • 7
  • 14
1

M-. which is bound to elpy-goto-definition will do the trick. Use M-* will let you jump back to the previous location int he buffer. This allows you to quickly check something and go back to the previous location.

I also use C-c C-o often (elpy-occur-definitions). This will open a window with all class and function is the current buffer. From that buffer, pressing Enter will land you on the definition in the source code.

user989762
  • 111
  • 2
  • Actually, AFAICT, `M-.` is bound to `xref-find-definitions` and `elpy-goto-definition` is not on any key by default (although it is on menus). Finding definitions in site packages does not seem to work at all well. – Robert P. Goldman May 21 '19 at 19:08
1

Today there is a wonderful development called LSP. Python is supported.

Client for Language Server Protocol (v3.14). lsp-mode aims to provide IDE-like experience by providing optional integration with the most popular Emacs packages like company, flycheck and projectile.

Emacs client/library for the Language Server Protocol

RichieHH
  • 848
  • 4
  • 9
1

Good question, that isn't available out of the box and is a handy feature of full blown IDEs. I do that with cscope, with a nice helm interface: http://wikemacs.org/wiki/Python#cscope It can answers questions like "where is this symbol defined ? Where is it used ?".

ps: in evil-mode we can go to the definition of a symbol in the same file with gd.

Ehvince
  • 1,091
  • 10
  • 14
  • I believe `gd` in evil only finds the first occurrence of the symbol in the file (despite the docstring: "Go to definition or first occurrence of symbol under point.") – Gordon Gustafson Jun 14 '16 at 02:27
0

Jedi is an awesome autocompletion/static analysis library for Python.I used it a lot back to when I was using vim.

Just like the golang autocompletion engine(i.e. gocode) works both for vim and emacs, the same Jedi engine works both for vim and emacs.

phye
  • 21
  • 3
0

For jedi we can use jedi:goto-definition to jump to definition.

xinfa tang
  • 151
  • 4
  • `jedi` does not have `jedi:goto-definition` – alper Feb 10 '21 at 15:08
  • jedi:goto-definition is defined in jedi-core package, you must activate jedi first: jedi:goto-definition is an interactive compiled Lisp function in ‘jedi-core.el’. (jedi:goto-definition &optional OTHER-WINDOW DEFTYPE USE-CACHE INDEX) Goto the definition of the object at point. – xinfa tang Mar 06 '21 at 03:02
  • I try it but still its output says as: `Wrong type argument: epc:manager, nil` – alper Mar 06 '21 at 12:09
  • probably better off using lsp now. – RichieHH Mar 15 '21 at 21:06