• Stars
    star
    121
  • Rank 293,924 (Top 6 %)
  • Language
    Emacs Lisp
  • License
    GNU General Publi...
  • Created about 7 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

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 the default xref.

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.

There’s also some ready made smart-jumps.

There are two ways to set up default registers.

Call smart-jump-setup-default-registers.

(use-package smart-jump
  :ensure t
  :config
  (smart-jump-setup-default-registers))

Bind commands to smart-jump-go, smart-jump-back and smart-jump-references.

(use-package smart-jump
  :ensure t
  :commands (smart-jump-go smart-jump-back smart-jump-references))

Upon running one of these commands, smart-jump will register jumps for you.

(use-package smart-jump
  :ensure t
  :bind (("M-." . smart-jump-go)
         ("M-," . smart-jump-back)
         ("M-?" . smart-jump-references)))

Defer smart-jump by using :bind.

(use-package smart-jump
  :ensure t
  :commands (smart-jump-go smart-jump-back smart-jump-references)
  :init
  (with-eval-after-load 'general
    (general-define-key
     :states '(normal visual motion)
     :keymaps 'override
     "M-." 'smart-jump-go
     "M-," 'smart-jump-back
     "M-?" 'smart-jump-references)))

Defer smart-jump in evil with general.

The deferred approaches allows one to save some startup-time by avoiding having to load the package as well as loop through all the jump registrations.

Examples

Bare minimum example

Sets up smart-jump for python-mode with anaconda. smart-jump will first attempt to jump using anaconda and, falling back to xref if anaconda fails.

(smart-jump-register :modes 'python-mode
                     :jump-fn 'anaconda-mode-find-definitions
                     :pop-fn 'anaconda-mode-go-back
                     :refs-fn 'anaconda-mode-find-references
                     :should-jump #'smart-jump-python-anaconda-available-p
                     :heuristic 'point
                     :async 600)

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 -> xref

  • 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.

Archived Code

Peek to Definition ./screenshots/peek.png

;;; This is code that used to be in smart-jump that I'm moving here now.
;;;###autoload
(defun smart-jump-peek ()
  "Peek at definition."
  (interactive)
  (smart-jump-make-peek-frame 'smart-jump-go))

(defun smart-jump-make-peek-frame (find-definition-function &rest args)
  "Make a new frame for peeking definition.

Credits to @tuhdo.

http://tuhdo.github.io/emacs-frame-peek.html"
  (let (doc-frame
        x y
        ;; 1. Find the absolute position of the current beginning of the
        ;; symbol at point, in pixels.
        (abs-pixel-pos (save-excursion
                         ;; (beginning-of-thing 'symbol)
                         (beginning-of-line)
                         (window-absolute-pixel-position))))
    (setq x (car abs-pixel-pos))
    (setq y (+ (cdr abs-pixel-pos)
               (frame-char-height)))

    ;; 2. Create a new invisible frame, with the current buffer in it.
    (setq doc-frame (make-frame '((name . "*SmartJump Peek*")
                                  (width . 80)
                                  (visibility . nil)
                                  (height . 20)
                                  (min-width  . t)
                                  (min-height . t)
                                  (border-width . 0)
                                  (internal-border-width . 0)
                                  (vertical-scroll-bars . nil)
                                  (horizontal-scroll-bars . nil)
                                  (left-fringe . 0)
                                  (right-fringe . 0)
                                  (tool-bar-lines . 0)
                                  (line-spacing . 0)
                                  (unsplittable . t)
                                  (no-other-frame . t)
                                  (no-special-glyphs . t))))

    ;; 3. Position the new frame right under the beginning of the
    ;; symbol at point.
    (set-frame-position doc-frame x y)

    ;; 4. Jump to the symbol at point.
    (with-selected-frame doc-frame
      (apply find-definition-function args)
      (recenter-top-bottom 0))

    ;; 5. Make frame visible again.
    (make-frame-visible doc-frame)))

Help Wanted :)

Look into issue tracker! Add tests! Add more default smart-jump registers.

Running Tests

cask
make test
make lint
make compile

More Repositories

1

dired-sidebar

Sidebar for Emacs leveraging Dired
Emacs Lisp
506
star
2

fussy

Emacs completion-style leveraging flx
Emacs Lisp
128
star
3

ibuffer-sidebar

A sidebar for IBuffer
Emacs Lisp
69
star
4

vscode-icon-emacs

Utility package that return vscode icons for emacs
Emacs Lisp
48
star
5

matcha

Collection of transients with a generic interface to launch them
Emacs Lisp
45
star
6

PhxSocketCPP

A C++ library to communicate with Phoenix Channels
C++
12
star
7

flycheck-swiftlint

Flycheck extension for swiftlint
Emacs Lisp
12
star
8

gud-lldb

LLDB Frontend for Gud
Emacs Lisp
11
star
9

flycheck-jest

Flycheck extenstion for jest
Emacs Lisp
10
star
10

flymake-racket

Flymake extension for Racket
Emacs Lisp
9
star
11

media-thumbnail

Emacs thumbnails for media
Emacs Lisp
9
star
12

evil-integrations

Provides a sane set of defaults for use with Evil Mode.
7
star
13

flycheck-gradle

Flycheck extension for projects that use gradle
Emacs Lisp
6
star
14

foo_tunes

Utility to maintain libraries in foobar2000 & itunes
Python
4
star
15

flycheck-xcode

Flycheck extension for Xcode
Emacs Lisp
3
star
16

flymake-gradle

Flymake extension for gradle
Emacs Lisp
3
star
17

flymake-ktlint

Flymake extension for ktlint
Emacs Lisp
2
star
18

Objective-C

Learning Objective-C
C
2
star
19

.zsh

Shell
1
star
20

point_of_sales_restaurant_app

iOS Restaurant Management Application
C
1
star
21

fruity-theme

A port of Fruity Theme in Vim https://github.com/mitsuhiko/fruity-vim-colorscheme
Emacs Lisp
1
star
22

xamarin-okhttp-okio-binding

A binding of Square's Okio project for Xamarin/C#
C#
1
star
23

Xamarin-AndroidAsync-Binding

C# binding for https://github.com/koush/AndroidAsync, adapted from https://github.com/thefactory/AndroidAsync-Sharp
C#
1
star
24

.dotfiles

Emacs Lisp
1
star