Skip to content
Oleh Krehel edited this page May 4, 2015 · 2 revisions

Table of Contents

Intro

lispy-goto, bound to g, is one of the most powerful features of lispy.

It uses CEDET to parse your source files and give you a list of tags to navigate to. The tags are the top-level expressions in your source files, such as:

  • function definitions
  • variable definitions
  • macro definitions
  • function calls

How parsing differs from evaluating

It is quite common for LISP programmers to navigate to a tag using evaluation rather than parsing. How it works: you load some code and your REPL (Emacs or SLIME or CIDER or Geiser) becomes aware of the locations of the symbols that you loaded. So you can ask your REPL to navigate you to a certain symbol that it knows about.

The advantages of evaluating over parsing:

  • It's slightly faster.

The advantages of parsing over evaluating:

  • You don't need to evaluate. This is an advantage for code that can't be evaluated, e.g. faulty code that's in the process of being written.

  • You can access libraries that you normally don't evaluate. For instance, you can access all 90000 tags in the Emacs source tree without requiring all libraries. To compare, I currently have around 40000 tags loaded by just requiring the stuff that I use.

  • Also note that if the code doesn't change, the parsing only has to be done once. After that the semanticdb cache is used. You can find it in ~/.emacs.d/semanticdb/.

  • You can navigate to general top-level function calls, not just to definitions.

How lispy-goto is better than other solutions

The ones that I'm aware of are imenu and helm-semantic.

Advantage 1: multiple files

Unlike other solutions, that work only on the current file, lispy-goto works on all files of the same type in the current directory. What this means is that if you are in an Elisp file, you can jump to all tags in all Elisp files in the current directory. But to jump to Clojure tags in the same directory you would need to switch to a Clojure file instead.

If you want to select from the tags in only the current file, you can do so with lispy-goto-local, bound to G.

If you want to select from all the tags in the current directory and all sub-directories recursively, you can do so with lispy-goto-recursive, bound to ogr. Note that it will take around 10 min to parse the whole Emacs tree, which isn't bad for 1500 files. But it's really fast for smaller projects, like org-mode or SLIME.

Advantage 2: more stuff gets parsed

There's an alist lispy-tag-arity that holds elements such as (setq . 2) or (org-defkey . 3), which I've customized heavily, and you can customize even further. The number by the construct name means how many of the arguments are significant to the name of the tag. For instance, for (declare-function . 1) only the first argument is significant, while for (global-set-key . 2) both the key binding and the command are significant.

You can see in the image below, how I navigate the whole org-mode code base to search for all bindings using org-defkey that match C-c C-x. So the input is defkey c-c c-x.

lispy-goto-org-defkey.png

There are currently 69 top-level tags that match. This amount will be auto-updated when the source code changes.

Advantage 3: the shortcut

While it's nice to have advanced functions, they can be underused since you can't bind all of them to short bindings. Well, it doesn't get shorter than g. And since the tag definition starts with an open paren, you're still in special after you jump, so you can jump further or navigate with other short bindings.

Customizing lispy-goto

lispy-completion-method

You have a choice between:

  • ivy (default)
  • helm (also very good)
  • ido (only usable with ido-vertical-mode)
  • default (icomplete-mode and icy-mode also fall here if you have them)

ivy screenshot

lispy-goto-ivy.png

helm screenshot

lispy-goto-helm.png

Note that helm matches 14 candidates, instead of ivy's 10, since it matches both "po.*cl" and "cl.*po", while ivy only matches the first regex.

lispy-tag-arity

You can extend this list to get more precise tag descriptions for a particular tag type. For instance, the popular use-package:

lispy-goto-use-package.png

lispy-command-name-face

This is an Elisp-only option. The interactive functions, i.e. commands, will be highlighted with this face to distinguish them from regular functions. This is great for discovering new packages: just install a package and quickly examine its commands with g.

lispy-helm-columns

This is a list of two integers, (70 80) by default. The first integer is the maximum length of the tag name. The second integer is the maximum total length of the tag name and the tag file.

Setup

You need to install clojure-semantic in order for the Clojure parser to work. For other dialects, nothing is required if you have Emacs24, since it already includes CEDET.