-
-
Notifications
You must be signed in to change notification settings - Fork 132
lispy goto
Table of Contents
- Intro
- How parsing differs from evaluating
- How lispy-goto is better than other solutions
-
Customizing
lispy-goto
- Setup
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
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.
The ones that I'm aware of are imenu
and helm-semantic
.
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
.
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
.
There are currently 69 top-level tags that match. This amount will be auto-updated when the source code changes.
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.
You have a choice between:
-
ivy
(default) -
helm
(also very good) -
ido
(only usable withido-vertical-mode
) -
default
(icomplete-mode
andicy-mode
also fall here if you have them)
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.
You can extend this list to get more precise tag descriptions for a particular tag type.
For instance, the popular use-package
:
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.
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.
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.