Giter Club home page Giter Club logo

dumb-jump's Introduction

dumb-jump

CI Coverage Status MELPA MELPA Stable

Dumb Jump GIF

About

Dumb Jump is an Emacs "jump to definition" package with support for 50+ 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:

  • Apex
  • Bash
  • C/C++
  • C#
  • Clojure
  • CoffeeScript
  • Common Lisp
  • Coq
  • Crystal
  • Dart
  • Elixir
  • Emacs Lisp
  • Erlang
  • F#
  • Faust
  • Fennel
  • Fortran
  • Go
  • Groovy
  • Haskell
  • Java
  • JavaScript
  • Julia
  • Kotlin
  • LaTeX
  • Lua
  • Matlab
  • Nim
  • Nix
  • Objective-C
  • OCaml
  • OpenSCAD
  • Org mode
  • Pascal
  • Perl
  • PHP
  • Protocol Buffers
  • Python
  • R
  • Racket
  • Ruby
  • Rust
  • Sass
  • Scala
  • Scheme
  • SML
  • Solidity
  • SQL
  • Swift
  • SystemVerilog
  • Tcl
  • Terraform / HCL
  • TypeScript
  • Vala
  • VHDL
  • Zig

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.

Installing ag or rg

Dumb Jump performs best with The Silver Searcher ag (ag install instructions) or ripgrep rg (rg install instructions) installed on your system.

Usage

Basic

To enable the xref backend, evaluate

(add-hook 'xref-backend-functions #'dumb-jump-xref-activate)

or add it to your initialisation file. Using this, you can now use M-. (or gd when using Evil).

Xref can be customized to use completing-read to select a target. That way a completion framework of your choice (Icomplete, Helm, Ivy, ...) will be used instead of the default pop-up buffer. To do this, evaluate

(setq xref-show-definitions-function #'xref-show-definitions-completing-read)

Note that the function xref-show-definitions-completing-read requires at least Xref 1.1.0. This can either be downloaded from ELPA or is bundled with Emacs 28.1 or newer.

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.

Example .dumbjump
-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.
  • To support more languages and/or definition types customize dumb-jump-find-rules variable.
  • (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 use git-grep if it's a git project and if not will try searchers in the following order ag, rg, grep (first installed wins). This is necessary if you want full control over the searcher Dumb Jump uses.
  • (setq dumb-jump-prefer-searcher 'rg) to let Dumb Jump know your searcher preference. If set this will still use git-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 the dumb-jump-force-searcher description. At this time setting this value is only necessary if you prefer rg but have ag 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").

If your project has multi-line method signatures you should use ag or rg version 0.10.0 or higher.

To learn more about how Dumb Jump picks a searcher see this issue and this pull request.

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

  1. M-x set-variable dumb-jump-debug t
  2. try to jump
  3. go to buffer *Messages*

More details here. Thanks to @cweiske and @Glumanda99

Obsolete commands and options

Older versions of dumb jump didn't use xref, and instead had custom commands. These, while marked obsolete, can still be used:

  • dumb-jump-go (former) core functionality. Attempts to jump to the definition for the thing under point. This has been replaced in the new interface with xref-find-definitions (M-.).
  • dumb-jump-back 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. This has been replaced with xref-pop-marker-stack (M-,), but is mostly equivalent.
  • dumb-jump-quick-look like dumb-jump-go but only shows tooltip with file, line, and context it does not jump.
  • dumb-jump-go-other-window exactly like dumb-jump-go but uses find-file-other-window instead of find-file
  • dumb-jump-go-prefer-external like dumb-jump-go but will prefer definitions not in the current buffer
  • dumb-jump-go-prefer-external-other-window expected combination of dumb-jump-go-prefer-external and dumb-jump-go-other-window
  • dumb-jump-go-prompt exactly like dumb-jump-go but prompts user for function to jump to

A few user options only have an effect when used with the legacy interface. These are:

  • dumb-jump-after-jump-hook (use xref-after-jump-hook instead)
  • dumb-jump-before-jump-hook (use xref-after-return-hook instead)
  • dumb-jump-selector
  • dumb-jump-aggressive
  • dumb-jump-use-visible-window
  • dumb-jump-confirm-jump-to-modified-file

The minor mode dumb-jump-mode binds a few of these commands by default.

If you still use Emacs 24 or older, you won't have xref, and have to use the legacy interface instead. In that case, there will also be no "obsolete" warnings.

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:

Most of these were sourced from this emacs StackExchange answer.

dumb-jump's People

Contributors

abend avatar adrieankhisbe avatar andreyorst avatar ashedko avatar cweiske avatar deuill avatar dleslie avatar fablhx avatar gleek avatar hinrik avatar ibrahima avatar jacktasia avatar jrosdahl avatar knu avatar lenbok avatar liangzan avatar magnetophon avatar meqif avatar murmour avatar netromdk avatar nhojb avatar nxtr avatar phikal avatar purcell avatar rgrinberg avatar twmr avatar volhovm avatar wamaral avatar wbolster avatar wilfred avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dumb-jump's Issues

completion/selection via ivy

it would be great if the jump options that dumb-jump discovered could be selected using ivy instead of the current pop-up. it would be great if it looks like a swiper-style or counsel-ag style selection.

perhaps @abo-abo would be so kind to leave a comment on how that is best achieved. does it need changes in dumb-jump? would a counsel-dumb-jump be a better option? if so, is dumb-jump structured correctly to provide counsel with the right information?

React Components

First of all this is really an amazing job.
On javascript code it works really well also on medium/big repositories. One thing that do not work well however are React components. usually they are just exported as normal classes (or functions or variables...) and the only unusual thing is that they appear in jsx code (e.g. <Component .... />)

Do you think would be hard to make them works, what implementations problems there may be?

P.S. thanks again for the effort

Ruby support?

Hello,

how difficult would it be to support Ruby? maybe simply copy-paste adapt python support?

dumb-jump cannot be used with files whose extensions end in numbers

I am in the process of trying to add fortran support to dumb-jump.

The regular expressions in dumb-jump-parse-response-line, i.e.

(s-split ":?[0-9]+:" resp-line)
(s-match ":?\\([0-9]+\\):" resp-line)

don't correctly handle the case when the filename ends in a number. Since the colon is optional, they confuse the file extension and the line number.

In this case, the value of resp-line looks like "/path/to/file.f90:1701: subroutine test(foo)"

Save before jump

Just wondering why is this necessary. It's not very convenient.

ES6 classes

Given the following scenario:

const instance = new MyCla|ss(3, 4);

Dumb jump will find the definition of MyClass if it defined as follows:

function MyClass(a, b) {
    this.a = a;
    this.b = b;
}

But it will not find the definition of MyClass if it defined using ES6 classes.

class MyClass {

    constructor(a, b) {
        this.a = a;
        this.b = b;
    }
}

I don't think jumping to the constructor would be necessary but it would be nice. IMO, jumping to class MyClass { would suffice.

Add option to set search scope as the first parent dir containing a VCS settings directory

Setting (setq dumb-limit-to-vcs-project t) and "jumping" within a file would search back up the directory tree, looking within each parent directory successively for a VCS settings directory (e.g. .git, .svn, etc), until reaching the main project directory defined by dumb-jump-default-project. If such a settings directory is found, this directory would be used as the "project" directory when performing searches.

For example:

code/               # `dumb-jump-default-project`
└── my-project/     # expected project dir
    ├── .git/       # VCS dir identifying expected project dir
    ├── my-defs.py  # location of target definition
    └── my-app.py   # current buffer location

In this case, searching would be scoped to my-project because it contains a .git directory. Should the .git directory be removed, scoping would fall back to code/ as set by dumb-jump-default-project.

Manual installation

Hi @jacktasia
I'd like to try your package, but I don't really want to use package.el.
I tried to just clone the repo and make install but it doesn't seem to be working.
Could you please describe manual installation process?
Thanks!

question: why not TAGS?

it would be helpful to me to know why I should use dumb-jump instead of TAGS. Personally, I generated TAGS files but what was missing was I couldn't just jump to the definition of a Rails function or the class that I was using in a Node project.

It might be helpful for others to compare and contrast the difference between using TAGS and dumb-jump.

C-M-g not working

Hello,
Thanks for developing dumb-jump.
This might rather be a issue with emac or meta-key mapping. I hope it is ok to ask this here.

I installed dumb-jump trough the package manager and everything works except for C-M-g.
(C-M-q works as expected, M-x dumb-jump-go works as expected)

When I use C-h k to check the mapping of C-M-g, then I get the mapping for C-g displayed. C-M-q however is displayed correctly.
Do you have any ideas why this could be and how to fix it? Could it have something to do with meta key mapping? I am working on a Linux cluster connected through ssh from Mac OSX using iterm. The meta-key mapping usually works for all other commands.

Many thanks,
Hannes

Add `:supports` property to rules

So we can set which search program (ag or grep) the rule supports. Stopping the need for a rule to support grep too, which often makes the regex way more complicated. Also opens the door to support other searchers like pt in interesting ways.

open in other window

i would love a dumb jump command that opens the definition in another window, just like find-file-other-window and switch-to-buffer-other-window.

otherwise, rock on. :)

Add location to find-tag

I can make a PR for this but wanted to check if I was overlooking a design choice. When I jump to a definition, I find myself typing M-* to jump back to my previous location. Is there a reason why you don't have (ring-insert find-tag-marker-ring (point-marker)) in the jump-go function?

faust definition is sometimes not found

A while ago I added faust to the supported languages.

Sometimes dumb-jump finds multiple definitions ( which is to be expected), without the correct one included.

Unfortunately, I have not yet been able to find out under which conditions this happens.

Quick look at the difinition

Sometime you just want to look at the definition without jumping and automatically close after that. So, something like dumb-jump-quick-look could open unfocused window which would be automatically closed after pressing any key.

Please add support to PL/SQL procedures and packages

In the same (projectile) directory tree.

Would be great to jump to package_name.procedure_name or package_name.function_name, and package_name.constant_name, where package_name is usually a package_name.(prc|pks|sql) file in the actual project directory tree.

Fall back to symbol search.

I use your dumb-jump and very happy with it!
But sometimes dumb-jump cannot find definitions, for example, functions defined by DSL.
In Emacs Lisp, dumb-jump cannot find dumb-jump-mode because it is defined by define-minor-mode.

;; Code in the dumb-jump repository.
(defun a ()
  (dumb-jump-mode)  ; NG
  (dumb-jump-go))   ; ok

I propose that dumb-jump should fall back to symbol search if it cannot find definitions.
Although dumb-jump produces many candidates in popup-menu, but I think it is more happy than "not found" because it is rare case.

For me, I use find-function to find definitions in Emacs Lisp.
This code is only an example.
This case can occur in Ruby and so on.

Not usable in shell

I'll often be investigating things inside an emacs shell. Either running tests or grepping around or whatever. From there I'd like to be able to put point on a symbol and invoke dumb-jump. But because the buffer is in shell-mode, it fails out. It'd be nice to be able to set a "default language" or something to let it at least attempt a jump.

Jump from function usage to definition and vice versa [PHP examples]

Currently I can jump from usage to definition, thanks to 7e25680 but can't go the other direction

PHP examples

definitions:

class Foo {
    function bar() {}
    static function bar() {}
}

function bar() {}

usages:

$bar = $foo->bar();
$bar = Foo::bar();
$bar = bar();

Explanation

If I am on a usage, I'd like to jump to the definition. e.g. possible regex:

/function\s+(bar)\s*\(/

If I have the cursor on the definition I'd like to jump to usages. e.g. possible regex:

/(?<!function\s)(bar)\s*\(/

Customizable key bindings?

Hello,

"C-M-p" is already used by (backward-list), a pretty useful command. Would it be possible to let the key-bindings to the user or at least make them customizable, so that (dumb-jump-back) could be bound somewhere else?

Anyhow, thank you for this great package!

ES6 arrow functions and methods.

Dumb jump currently wont find arrow function definitions or methods in javascript. Ideally it would be able to find funcName when defined in a way below;

let funcName = (foo) => "bar";

const funcName = (foo) => "bar";

const funcName = (foo) => {
  return "bar";
}

const obj = {
  funcName: (foo) => {
    return "bar";
  }
}

const obj = {
  funcName(foo) {
    return "bar";
 }
}

Trouble with Emacs 24.3 on Ubuntu 14.04

I installed from MEPLA (version 20160427) and get this error when I try to dumb-jump-go in some Go source code:

dumb-jump-fetch-results: Wrong number of arguments: #[(thing) "^HÂN\203^K^@^HÂN \207Ã^H!\211^Y\205^X^@  @       A{)\207" [thing bounds thing-at-point bounds-of-thing-at-point] 3 ("/usr/share/emacs/24.3/lisp/thingatpt.elc" . 2294)], 2

I'm using the emacs24-nox package, version 24.3+1-2ubuntu1 and M-x version says GNU Emacs 24.3.1 (x86_64-pc-linux-gnu) of 2014-03-07 on lamiak, modified by Debian.

Manually set project root

dumb-jump uses the first project root indicator file it finds to set the project root to its containing directory.

This approach does not work for complex projects in which multiple git checkouts are used:

php-typo3-project/
+ typo3conf/
|  + ext/
|     + extension/
|        + .gitignore
|     + extension2/
|        + .gitignore
+ typo3_src/
+ .gitignore

When using dumb-jump on a file in php-typo3-project/typo3conf/ext/extension/src/Foo.php, it finds php-typo3-project/typo3conf/ext/extension/ as project root.
I'd rather want to have php-typo3-project as root.

c++ jumps to slightly wrong location

❑ marks the cursor. ⬱ where it jumps. ⟵ where it should jump

from here:

    if(_adaptive && !pixContribs.ProcessPixelDone())
    {
      _extrapolateRadianceValid(pixContribs,hit);
      _process❑PixelOverlap(hit,hit.directIllum.data(), 
        1/*thrElevImage[idx]*/,pixContribs,GetOctree<TRecord>());
      pixContribs.SetProcessPixelDone();
    }
    break;

to here:

 // --------------------------------------------------------------------------
 //  CAdaptiveCaching::_processPixelOverlap()                                      ⬱ 
 // --------------------------------------------------------------------------
 template<class TRecord,class TContribArray>
 int
 CAdaptiveCaching::_processPixelOverlap(const CHitInfoLite &hit,                     ⟵ 
                                        const float *directIllum,
                                        const float  thresholdElevation,
                                        TContribArray &carray,
                                        CRCOctree<TRecord> *octree)
 {

Want to jump to method definition but getting all variables as results [PHP]

Using PHP

  • It would be nice if methods and variables were not mixed in search results.
  • It would also be nice to jump to the method definition if using C-M-g on a method usage.

I don't know, but maybe it could include open parentheses and $ in regex (or whatever is used to search) to distinguish methods from variables?

Also searching for usage vs definition would be pretty cool.

e.g.

if the cursor is on fooBar() usage (i.e. ->fooBar() search for fooBar() definition (function fooBar() and if cursor is on the definition, search for usages?

Image -- cursor on method usage but getting variables as results:

dumb-jump

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.