dumb-jump
About
Dumb Jump is an Emacs "jump to definition" package with support for 40+ programming languages that favors "just working". This means minimal -- and ideally zero -- configuration with absolutely no stored indexes (TAGS) or persistent background processes. Dumb Jump requires at least GNU Emacs 24.3
.
How it works
Dumb Jump uses The Silver Searcher ag
, ripgrep rg
, or grep
to find potential definitions of a function or variable under point. It uses a set of regular expressions based on the file extension, or major-mode
, of the current buffer. The matches are run through a shared set of heuristic methods to find the best candidate to jump to. If it can't decide it will present the user with a list in a pop-menu, helm, or ivy (see dumb-jump-selector
).
Success Rate
For the currently supported languages it seems to do a good job of finding what you want. If you find a case where it does not work as expected do not hesitate to open an issue. It can be slow if it needs to use grep
and/or a project is large. Although it can be sped up by installing ag
or installing rg
and/or creating a .dumbjump
file in your project's root directory with paths that should be excluded (see configuration).
Supported Languages
There is currently basic support for the following languages:
- Bash
- C/C++
- C#
- Clojure
- CoffeeScript
- Common Lisp
- Coq
- Crystal
- Elixir
- Emacs Lisp
- Erlang
- F#
- Faust
- Fortran
- Go
- Groovy
- Haskell
- Java
- JavaScript
- Julia
- Kotlin
- LaTeX
- Lua
- Matlab
- Nim
- Nix
- Objective-C
- OCaml
- OpenSCAD
- Pascal
- Perl
- PHP
- Protocol Buffers
- Python
- R
- Ruby
- Rust
- SML
- Scala
- Scheme
- SQL
- Swift
- SystemVerilog
- Vala
- VHDL
If you have any issues with the existing languages, or you want support for another one, then please open an issue. PRs are also welcome. If you'd like to add a language these PRs for lua and rust are good examples.
Installing
The recommended way to install Dumb Jump is via package.el
. It's available on MELPA: M-x package-install dumb-jump
Spacemacs
If you're using an up-to-date Spacemacs, then you already have Dumb Jump by default just make sure you install ag
or rg
(see below) to ensure you have the best experience.
ag
or rg
Installing Dumb Jump performs best with The Silver Searcher ag
(ag install instructions) or ripgrep rg
(rg install instructions) installed on your system.
Usage
Basic
Adding (dumb-jump-mode)
to your .emacs
will enable the key bindings for two interactive Dumb Jump functions:
dumb-jump-go
C-M-g core functionality. Attempts to jump to the definition for the thing under pointdumb-jump-back
C-M-p jumps back to where you were when you jumped. These are chained so if you go down a rabbit hole you can get back out or where you want to be.dumb-jump-quick-look
C-M-q likedumb-jump-go
but only shows tooltip withfile
,line
, andcontext
it does not jump.dumb-jump-go-other-window
exactly likedumb-jump-go
but usesfind-file-other-window
instead offind-file
dumb-jump-go-prefer-external
likedumb-jump-go
but will prefer definitions not in the current bufferdumb-jump-go-prefer-external-other-window
expected combination ofdumb-jump-go-prefer-external
anddumb-jump-go-other-window
dumb-jump-go-prompt
exactly likedumb-jump-go
but prompts user for function to jump to instead of using symbol at point
Configuration
Excluding project directories
Dumb Jump will automatically look for a project root. If it's not finding one then either put a .dumbjump
file in your project root and optionally add excluded directories to make it faster.
Project root directory denoters: .dumbjump
.projectile
.git
.hg
.fslckout
.bzr
_darcs
.svn
Makefile
PkgInfo
-pkg.el
.
If you want to stop a directory from registering as the project root (and have Dumb Jump keep looking) add an empty .dumbjumpignore
file in that directory.
.dumbjump
Example -tests
-node_modules
-build
-images
+../some-lib/src
+/usr/lib/src
NOTE When adding paths outside of the project (using +
) ensure you use dumb-jump-force-searcher
of either 'ag
or 'rg
(see below). This is required because the default searcher (git-grep
) won't be able to search outside of the project root. This edge case will be fixed in a future release. That is, git-grep
will NOT be set as the default searcher if a .dumbjump
is present with a +
path outside of the repo.
.emacs
options
(setq dumb-jump-default-project "~/code")
to change default project if one is not found (defaults to~
)(setq dumb-jump-quiet t)
if Dumb Jump is too chatty.(setq dumb-jump-confirm-jump-to-modified-file nil)
to avoid being prompted for confirmation if you attempt to jump to a file that has been modified and not saved. This defaults tot
because jumping to modified files results in you jumping to a location that may no longer be current.- To support more languages and/or definition types customize
dumb-jump-find-rules
variable. (add-hook 'dumb-jump-after-jump-hook 'some-function)
to execute code after you jump(setq dumb-jump-selector 'ivy)
to use ivy instead of the default popup for multiple options.(setq dumb-jump-selector 'helm)
to use helm instead of the default popup for multiple options.(setq dumb-jump-force-searcher 'rg)
to force the search program Dumb Jump should use. It will always use this searcher. If not set (nil
) Dumb Jump will usegit-grep
if it's a git project and if not will try searchers in the following orderag
,rg
,grep
(first installed wins). This is necessary if you want full control over the searcher Dumb Jump uses.(setq dumb-jump-aggressive nil)
to only automatically jump if there's only one match and otherwise present you with a list. This defaults tot
, which means it will try its best to guess where you want to jump and only if it can't then give you a list of matches.(setq dumb-jump-use-visible-window nil)
ift
(the default) when you're using multiple windows/panes and the file to jump to is already open in one of those windows then dumb jump will focus that window and jump there instead of within your current window.(setq dumb-jump-prefer-searcher 'rg)
to let Dumb Jump know your searcher preference. If set this will still usegit-grep
if it's a git project (because it's the fastest), but will you use whatever you set here in any other situation. If not set Dumb Jump will follow the same order as mentioned in thedumb-jump-force-searcher
description. At this time setting this value is only necessary if you preferrg
but haveag
installed too.(setq dumb-jump-git-grep-search-args "")
to set additional command line arguments when using git-grep for searching (defaults to""
).(setq dumb-jump-ag-search-args "")
to set additional command line arguments when using ag for searching (defaults to""
).(setq dumb-jump-rg-search-args "")
to set additional command line arguments when using rg for searching (defaults to"--pcre2"
).
you should use ag
or rg
with a version higher than 0.10
.
If your project has multi-line method signatures To learn more about how Dumb Jump picks a searcher see this issue and this pull request.
use-package
example configuration.
I personally no longer use the dumb-jump-mode
keybindings that were inspired by IntelliJ's emacs bindings. I use use-package
like so:
(use-package dumb-jump
:bind (("M-g o" . dumb-jump-go-other-window)
("M-g j" . dumb-jump-go)
("M-g i" . dumb-jump-go-prompt)
("M-g x" . dumb-jump-go-prefer-external)
("M-g z" . dumb-jump-go-prefer-external-other-window))
:config (setq dumb-jump-selector 'ivy) ;; (setq dumb-jump-selector 'helm)
:ensure)
Hydra for effieciency
If you have Hydra installed, the following is an example hydra for easily using Dumb-Jump and not needing to remember the bindings or function names:
(defhydra dumb-jump-hydra (:color blue :columns 3)
"Dumb Jump"
("j" dumb-jump-go "Go")
("o" dumb-jump-go-other-window "Other window")
("e" dumb-jump-go-prefer-external "Go external")
("x" dumb-jump-go-prefer-external-other-window "Go external other window")
("i" dumb-jump-go-prompt "Prompt")
("l" dumb-jump-quick-look "Quick look")
("b" dumb-jump-back "Back"))
It can be explicitly bound or used inside another hydra (if you already use something like Avy/Ace or similar for general "jumping").
Debugging a jump
- M-x
set-variable dumb-jump-debug t
- try to jump
- go to buffer
*Messages*
More details here. Thanks to @cweiske and @Glumanda99
Why?
I wanted "jump to definition" functionality to "just work" in emacs. I use IntelliJ for Java and this functionality is basically the only thing I miss when I switch back to emacs for work in other languages. There are certainly other packages that offer this type of functionality, but they all require significantly more configuration and are often limited to a particular language. An alternative may be worth setting up if you are in a specific project or language often (see alternatives).
Contributing
Feedback is very welcome via GitHub issues. I will consider supporting other languages either via issue request or PR. If submitting a PR then please add tests as well.
Running Tests
Opening a PR will use CircleCI to run all the tests against all the supported emacs versions and search programs.
Running tests locally
There are a lot of options for running the tests locally:
Basic/Classic
requires Cask using your local emacs
cd /path/to/dumb-jump
cask
make test
Concurrent
requires golang and Cask using your local emacs
cd /path/to/dumb-jump
cask
make test-concurrent
Docker (latest emacs)
only requires docker and runs tests against emacs 26.1
cd /path/to/dumb-jump
cask
make test-in-docker
Docker (all supported emacs versions)
only requires docker and runs tests against all supported emacs versions
cd /path/to/dumb-jump
cask
make test-all-in-docker
Alternatives
Here is a list of potential alternative packages for emacs:
- Tags supports multiple languages
- GNU Global supports multiple languages
- Tern for JavaScript
- elpy for Python
- robe for Ruby
Most of these were sourced from this emacs StackExchange answer.