lispy 0.26.0 is out29 May 2015
Lispy 0.25.0 came out 2 months ago; 177 commits later, comes version 0.26.0. The release notes are stored at Github, and I'll post them here as well.
The coolest changes are the new reader-based M, which:
- Gives out very pretty output, with minor diffs for actual code, which is quite impressive considering all newline information is discarded and then reconstructed.
- Works for things that Elisp can't read, like
#<marker ...>etc, very useful for debugging.
- Customizable rule sets; rules for Elisp and Clojure come with the package.
The improvements to g and G also great:
- Because of caching, the prettified tags can be displayed in less
lisp/directory, which has 21256 tags in 252 files.
- The tags collector looks at file modification time, so you get the updated tags right after you save.
The details for these and other features follow below.
- C-k should delete the whole multi-line string.
- y should work for all parens, not just
- p should actually eval in other window for
- Prevent pairs inserting an extra space when at minibuffer start.
- ol works properly for active region.
- xf will pretty-print the macros for Elisp.
- M-m works better when before
- Fix ', ^ after a
- Improve / (splice) for quoted regions.
- Z works with
- The new M is used in xf.
- Allow to flatten Elisp
- c should insert an extra newline for top-level sexps.
Paredit key bindings
You can have only Paredit + special key bindings by using this composition of key themes:
(lispy-set-key-theme '(special paredit))
The default setting is:
(lispy-set-key-theme '(special lispy c-digits))
New algorithm for multi-lining
M is now bound to
lispy-alt-multiline instead of
lispy-multiline. It has a much better and more customizable
See these variables for customization:
They are set to reasonable defaults. But you can customize them if you feel that a particular form should be multi-lined in a different way.
lispy-multiline-threshold is a bit of ad-hoc to make things nice. Set this to nil if you want a completely rigorous multi-line. With the default setting of 32, expressions shorter than this won't be multi-lined. This makes 95% of the code look really good.
The algorithm has a safety check implemented for Elisp: if
read on the transformed expression returns something different than
read on the original expression, an error will be signaled and no change will be made. For expressions that can't be
read, like buffers/markers/windows/cyclic lists/overlays, only a warning will be issued (
lispy can read them, unlike
d and > give priority to
For the expression
(a) will be considered the sexp at point, instead of
(b). This is consistent with
show-paren-mode. If a space is present, all ambiguities are resolved anyway.
b works fine even if the buffer changes
I've switched the point and mark history to markers instead of points. When the buffer is changed, the markers are updated, so b will work fine.
Extend Clojure reader
In order for i (prettify code) to work for Clojure, it must be able to read the current expression. I've been extending the Elisp reader to understand Clojure. In the past commits, support was added for:
- empty sets
- auto-symbols, like
Extend Elisp reader
It should be possible to read any
#<...> form, as well as
g and G get a persistent action for
This is a powerful feature that the
helm back end has had for a long time. When you press g, C-n and C-p will change the current selection. But C-M-n and C-M-p will change the current selection and move there, without exiting the completion.
This also means that you can call
ivy-resume to resume either g (
e works with
As you might know, the regular C-x C-e or
eval-buffer will not reset the values of
defcustom and such (you need C-M-x instead). But e does it, now also for
Improve faces for dark backgrounds
I normally use a light background, so I didn't notice before that the faces looked horrible with a dark background.
The ` will quote the region
If you have a region selected, pressing ` will result in:
Customize the file selection back end for V
lispy-visit) allows to open a file in current project. Previously, it used
Now it uses
find-file-in-project by default, with the option to customize to
Fixup calls to
looking-back isn't very efficient, so it's preferable to avoid it or at least add a search bound to improve efficiency. Also the bound became mandatory in 25, while it was optional before.
M-m will work better in strings and comments.
See the relevant test:
(should (string= (lispy-with "\"See `plu|mage'.\"" (kbd "M-m")) "\"See ~`plumage'|.\""))
Thanks to this, to e.g. get the value of a quoted var in a docstring or a comment, or jump to its definition, you can M-m. Then, you can step-in with i to select the symbol without quotes.
Update the tags strategy
A much better algorithm with caching an examining of file modification time is used now. This means that the tags should be up-to-date 99% of the time, even immediately after a save, and no necessary re-parsing will be done. And it all works fine with the
1% of the time,
lispy-tag-arity stops working, I don't know why, since it's hard to reproduce. You can then pass a prefix arg to refresh tags bypassing the cache, e.g 2g or 2G.
Also a bug is fixed in Clojure tag navigation, where the tag start positions were off by one char.
The fetched tags retrieval is fast: less than
0.15s on Emacs'
lisp/ directory to retrieve 21256 tags from 252 files. Which means
it's lightning fast on smaller code bases (
lispy has only 651 tags).
xj can also step into macros
lispy-debug-step-in, bound to xj locally and C-x C-j globally can now step into macros, as well as into functions. This command is very useful for Edebug-less debugging. Stepping into macros with
&rest parameters should work fine as well.
p can now lax-eval function and macro arguments
When positioned at function or macro args, p will set them as if the function or macro was called with empty args, or the appropriate amount of nils. If the function is interned and interactive, use its interactive form to set the arguments appropriately.
Again, this is very useful for debugging.
Allow to paste anywhere in the list using a numeric arg
As you might know, P (
lispy-paste) is a powerful command that:
- Replaces selection with current kill when the region is active.
- Yanks the current kill before or after the current list otherwise.
Now, you can:
- Yank the current kill to become the second element of the list with 2P
- Yank the current kill to become the third element of the list with 3P
It's OK to pass a larger arg than the length of the current list. In that case, the paste will be made into the last element of the list.
Update the way / (
When there's no next element within parent, jump to parent from appropriate side. When the region is active, don't deactivate it. When splicing region, remove random quotes at region bounds.
This change makes the splice a lot more manageable. For example,
starting with this Clojure code, with
| marking the current point:
(defn read-resource "Read a resource into a string" [path] (read-string |(slurp (clojure.java.io/resource path))))
A double splice // will result in:
(defn read-resource "Read a resource into a string" [path] |(read-string slurp clojure.java.io/resource path))
After xR (reverse list), 2 SPC (same as
-> (plain insert),
[M (back to parent and multi-line), the final result:
(defn read-resource "Read a resource into a string" [path] |(-> path clojure.java.io/resource slurp read-string))
This also shows off xR -
lispy-reverse, which reverses
the current list. Finally, reverting from the last code to the
initial one can be done simply with xf - it will flatten
-> macro call.
Thanks to all who contributed, enjoy the new stuff. Would also be nice to get some more feedback and bug reports. Currently, it might seem that a large part of the features are either perfect or unused.