/smart-jump

Primary LanguageEmacs LispGNU General Public License v3.0GPL-3.0

Smart Jump

https://travis-ci.org/jojojames/smart-jump.svg?branch=master https://melpa.org/packages/smart-jump-badge.svg

About

This packages tries to smartly go to definition leveraging several methods to do so.

If one method fails, this package will go on to the next one, eventually falling back to dumb-jump.

Install

Install using use-package.

(use-package smart-jump :ensure t)

Take a look at the examples below to register a smart-jump and then use it with the standard jump keys. (e.g. M-., M-, M-?).

Alternatively, clone this repo, add it to Emacs’ load-path and then require smart-jump.

Examples

Bare minimum example

Sets up smart-jump for js2-mode with default settings. Defaults will use the built-in xref functions first and fall back to dumb-jump if that fails.

(smart-jump-register :modes '(js2-mode))

Multiple modes

Sets up smart-jump for both emacs-lisp-mode and lisp-interaction-mode.

(smart-jump-register :modes '(emacs-lisp-mode lisp-interaction-mode)
                     :jump-fn 'elisp-slime-nav-find-elisp-thing-at-point
                     :pop-fn 'pop-tag-mark
                     :should-jump t
                     :heuristic 'error
                     :async nil)

Supporting Asynchronous Functions

Sometimes GoToDefinition is written in an asynchronous fashion which makes it tricky to fallback to the next GoToDefinition method. This package supports that case. Just set the :async parameter.

(smart-jump-register :modes 'java-mode
                     :jump-fn 'ggtags-find-tag-dwim
                     :pop-fn 'ggtags-prev-mark
                     :should-jump t
                     :heuristic 'point
                     :async t)
;; This sets a custom timeout.
(smart-jump-register :modes 'csharp-mode
                     :jump-fn 'omnisharp-go-to-definition
                     :pop-fn 'pop-tag-mark
                     :should-jump t
                     :heuristic 'point
                     :async 500)

Finding References with Fallback

(smart-jump-register :modes 'tide-mode
                     :jump-fn 'tide-jump-to-definition
                     :pop-fn 'tide-jump-back
                     :refs-fn 'tide-references
                     :should-jump t
                     :heuristic 'point
                     :async t)

A more complex example

Register different GoToDefinition functions with c-mode.

(smart-jump-register :modes '(c-mode c++-mode)
                     :jump-fn 'ggtags-find-tag-dwim
                     :pop-fn 'ggtags-prev-mark
                     :refs-fn 'ggtags-find-reference
                     :should-jump t
                     :heuristic 'point
                     :async 500
                     :order 2)

(smart-jump-register :modes '(c-mode c++-mode)
                     :jump-fn 'rtags-find-symbol-at-point
                     :pop-fn 'rtags-location-stack-back
                     :refs-fn 'rtags-find-all-references-at-point
                     :should-jump (lambda ()
                                    (and
                                     (fboundp 'rtags-executable-find)
                                     (rtags-executable-find "rc")
                                     (rtags-is-indexed)))
                     :heuristic 'point
                     :async 500
                     :order 1)

In this case, the fallback strategy is ->

  • For Jumping

rtags-find-symbol-at-point -> ggtags-find-tag-dwim -> dumb-jump-go

  • For Finding References

rtags-find-all-references-at-point -> ggtags-find-reference -> smart-jump-simple-find-references

The :order keyword in this case designates the sort order of the jumps.

Take a look at this for more examples.

Help Wanted :)

Add more fallback methods and/or language support plists.

Async code handling is fairly duplicated.

Add tests!

Running Tests

cask
make test
make lint
make compile