Short and sweet LISP editing
Bot releases are visible (Hide)
(
.dolist
.)
.,
.&key
arguments.defsubst
.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))
M is now bound to lispy-alt-multiline
instead of lispy-multiline
. It has a much better and more customizable algorithm.
See these variables for customization:
lispy-multiline-threshold
lispy--multiline-take-3
lispy--multiline-take-3-arg
lispy--multiline-take-2
lispy--multiline-take-2-arg
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 read
).
lispy-right
For the expression (a)|(b)
, (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.
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.
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:
p1__7041#
It should be possible to read any #<...>
form, as well as #1
-type forms.
ivy
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 (lispy-goto
) or
G (lispy-goto-local
).
defvar-local
As you might know, the regular C-x C-e or eval-buffer
will not reset the values of defvar
, defcustom
and such (you need C-M-x instead). But e does it, now also for defvar-local
.
I normally use a light background, so I didn't notice before that the faces looked horrible with a dark background.
If you have a region selected, pressing ` will result in:
`symbol'
V (lispy-visit
) allows to open a file in current project. Previously, it used projectile
.
Now it uses find-file-in-project
by default, with the option to customize to projectile
.
looking-back
Apparently, 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.
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.
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 lispy-tag-arity
modifications.
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).
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.
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.
As you might know, P (lispy-paste
) is a powerful command that:
Now, you can:
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.
lispy-splice
) worksWhen 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 C-f), ->
(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 the ->
macro call.
Published by abo-abo over 9 years ago
minibuffer-inactive-mode
to the lispy-elisp-modes
list. It means that you can eval there if you want.lispy-visit
) should turn on projectile-global-mode
if it's not on.lispy-multiline
) works better for Clojure: the regexes for vectors, maps and sets have been improved.lispy-back
The movement commands, such as:
lispy-left
, lispy-down
etc.)lispy-flow
)lispy-ace-paren
)lispy-tab
), only when called for an active regionwill not store each movement in the point-and-mark history. You can press b to go back in
history. This is especially useful for h, l, and f, since they are
not trivially reversible.
b was previously bound to lispy-store-region-and-buffer
, so you could do Ediff with
b and B. Now it's bound to xB.
C-d (lispy-delete
) when positioned at the start of a comment, and with only whitespace
before the start of the line, will delete the whole comment.
If you want to un-comment, just use C-u ; from any point in the comment.
xf (lispy-flatten
) now also works for Clojure, before it was only for Elisp.
|(->> [1 2 3 4 5]
(map sqr)
(filter odd?))
When you press xf you get this:
|(filter odd? (map sqr [1 2 3 4 5]))
Start with:
|(map odd? [1 2 3 4 5])
After xf:
(let [f odd? coll [1 2 3 4 5]]
(lazy-seq (when-let [s (seq coll)]
(if (chunked-seq? s)
(let [c (chunk-first s)
size (int (count c))
b (chunk-buffer size)]
(dotimes [i size]
(chunk-append b (f (.nth c i))))
(chunk-cons (chunk b)
(map f (chunk-rest s))))
(cons (f (first s))
(map f (rest s)))))))
A bit of a gibberish, but at least we can confirm that map
is indeed lazy.
Example function:
(defn sqr [x]
(* x x))
This one requires the function to be properly loaded with C-c C-l (cider-load-file
),
otherwise Clojure will not know the location of the function.
Example statement:
(+ |(sqr 10) 20)
After xf:
(+ |(let [x 10]
(* x x)) 20)
This is similar to the lax eval for Elisp. If you mark an expression with a region:
asdf [1 2 3]
and press e, you will actually eval this:
(do (def asdf [1 2 3])
asdf)
You can do this for let bindings, it's super-useful for debugging. The rule is that if the first
element of the region is a symbol, and there's more stuff in the region besides the symbol, a lax
eval will be performed.
If CIDER isn't live, e will start it and properly eval the current statement.
Since Elisp is a LISP-2, there can be a function and a variable with the same name. F
(lispy-follow
) prefers functions, but now 2F will prefer variables.
Starting with:
|(filter odd? (map sqr [1 2 3 4 5]))
Pressing 2e gives:
(filter odd? (map sqr [1 2 3 4 5]))
;; =>
;; (1 9 25)
This works for all dialects, so you can also have:
(symbol-function 'exit-minibuffer)
;; =>
;; (closure (t)
;; nil "Terminate this minibuffer argument." (interactive)
;; (setq deactivate-mark nil)
;; (throw (quote exit)
;; nil))
or
*MODULES*
;; =>
;; ("SWANK-ARGLISTS" "SWANK-FANCY-INSPECTOR" "SWANK-FUZZY" "SWANK-C-P-C"
;; "SWANK-UTIL" "SWANK-PRESENTATIONS" "SWANK-REPL"
;; "SWANK-TRACE-DIALOG" "SB-CLTL2" "SB-POSIX" "SB-INTROSPECT")
To do the last eval you need to be in special. So first mark the symbol *MODULES*
with a region.
A convenient function to mark the current symbol is M-m (lispy-mark-symbol
).
lispy-occur
) now has an ivy
back endlispy-occur
launches an interactive search within the current top-level expression, usually a
defun. This is useful to see where a variable is used in a function, or to quickly navigate to a
statement.
You can customize lispy-occur-backend
to either ivy
(the default) or helm
(if you have it,
since it's no longer a dependency of lispy
).
lispy-completion-method
Now it's the default one for navigating to tags. You can select alternatively helm
or ido
if you
wish.
ace-jump-mode
Instead the dependency on ace-window
will be re-used. This allows for a lot of code
simplifications and better tests.
New custom variables:
lispy-avy-style-char
: choose where the overlay appears for Q (lispy-ace-char
)lispy-avy-style-paren
: choose where the overlay appears for q (lispy-ace-paren
)lispy-avy-style-symbol
: choose where the overlay appears for a (lispy-ace-symbol
)lispy-ace-subword
) and H (ace-symbol-replace
).There's also lispy-avy-keys
, which is a
... z
by default.
lispy-compat
This is a list of compatibility features with other packages, such as edebug
and god-mode
.
They add overhead, so you might want to turn them off if you don't use the mentioned packages.
You can navigate to a symbol definition in Scheme with F. This feature was already
in place for Elisp, Clojure and CL.
Published by abo-abo over 9 years ago
lispy--eval-elisp-form
first arg is now named lispy-form
instead of form
. It was impossibleform
variable with the previous behavior.defn
) from Clojure source.delete-region
in some obscure branches.lispy-paste
) will add a newline when called from start of line. This way,lispy-clone
). Of course, it's more flexible: youlispy-bind-variable
) now works on regions as well. Use it to bind the currentiedit
. When you're done with iedit
, presslispy-mark-symbol
) to exit iedit
. If you need to move the let binding around, uselispy-convolute
) and h (lispy-left
).loaddefs.el
for Elisp.defhydra
to lispy-tag-arity
: now g will recognize defhydra
statements.lispy-outline
was updated to match the standard ^;;;
outline regex. Try pressing Ilispy-eval
functions will preserve the match data.undercover
/Coveralls test coverage report.lispy-ace-symbol-replace
) is now a Hydra: type h to delete more, typelispy-ace-char
) now uses avy
to jump. This change allows to cover thisdolist
variables in Elisp.(defun range (a b)
(message "called range")
(number-sequence a b))
(dolist |(i (range 1 3))
(message "i=%d" i))
Pressing p with point where |
is, will
range
and set i
to 1i
to 2i
to 3i
to nilrange
and set i
to 1This is another step toward edebug
-less debugging, adding to special behavior for let
, cond
and labels
.
lispy-helm-columns
is now a list '(60 80)
. The first number is the width of the tag namelispy-shiftab
) is now a two-way cycle, instead of three-way, like org-mode
.Published by abo-abo over 9 years ago
()
in (eq (char-before) ?\()
being interpreted as nil by lispy--read
,
as identity
for eval purposes: it's now possible to eval e.g.(list (list ,foo)|)
, which will return the result of (list foo)
.ace-window
. Afterwards, if the window configuration doesn't change, the target window will stay the sameorg-mode
lispy-move-beginning-of-line
which either moves to beginning of line,A new custom variable lispy-completion-method
can now take 3 values:
helm
- completes with helm
. Yep.ido
ido
, strings don't include filename to save spaceido-vertical-mode
is on, gives strings same as for helm
default
- falls back to other completion methods:
icomplete-mode
, when it's onicy-mode
, when it's oncompleting-read
when nothing else is onWhen at outline:
Published by abo-abo over 9 years ago
~
.'( )
to '()
instead of 'nil
.lispy-kill-word
. Similar to kill-word
, butlispy-backward-kill-word
. Similar to backward-kill-word
, butlispy-kill-sentence
. Similar tokill-sentence
, but the sentence now the current list.lispy-forward
is bound to C-M-n, in addition to ]
lispy-backward
is bound to C-M-p, in addition to [
The obsolete aliases lispy-out-forward
, lispy-out-backward
and
lispy-out-forward-nostring
were removed.
lispy-clockwise
and lispy-counterclockwise
have been marked as
obsolete and will be removed in 0.23.0
. There's no need to replace
them, since they don't do much.
Published by abo-abo over 9 years ago
cmd
in lispy--insert-or-call
company-mode
completion.xh (describe) now describes variables in addition to functions.
y (occur) pre-select was improved.
y (occur) will deactivate mark.
C (convolute) now works from both sides, not just from the front.
t (teleport) will now work only within the current defun. This will make it more consistent, since
it will not depend on the window scroll amount.
e (eval) is greatly improved for Clojure. It will now concatenate both the output
and the eval result, with output colored as string.
i (indent) now works also with Clojure map literals.
B (ediff-bounds) the ediff will try re-use the current window configuration.
C-4 C-h or C-h F1 will describe the bindings
C-d and DEL are now less whitespace-hungry and more intuitive
xj (debug-step-in) now works for adviced functions
A (beginning-of-defun) will restore point and mark when called twice
S (stringify) or C-u " (quote) don't move the point.
S (stringify) will keep the region.
' (tick) will unquote if the current region is a string. So now you can
quote/unquote region with "/'.
m and M-m will mark the full sexp, i.e. together with ,@'
stuff.
i now works for marked quoted symbols, so if you have
|(add-to-list 'auto-mode-alist '(\"\\\\.cache\\\\'\" . emacs-lisp-mode))
you can eval auto-mode-alist
with mijie.
lispy-bind-variable
: the current expression will be moved toiedit
. You can use M-miedit
and to mark the newly created name. Then, if you want to move the let
, just uselispy-open-line
: it's useful to add a new line after the currentlispy-alt-line
is the alternative newline. It might be a bit confusing, so it's not bound.lispy-mode
for cider-repl-mode
and slime-repl-mode
, RET will work.cl-labels
: it will appropriately bind the function at point.The outline style was changed, to allow for nested outlines.
org-mode
(3-way cycle)org-mode
(3-way cycle)org-mode
.(should
statement in lispy-test.el
,Here's another preview, with special handling of point, mark, region and show-paren-mode
:
In an effort to simplify the notation, lispy-out-forward
was renamed to lispy-right
; and lispy-out-backward
was renamed to lispy-left
.
The old names are retained as obsolete aliases for the current functions. They will be removed in the next release.
Published by abo-abo almost 10 years ago
w/s can move quoted sexps, e.g. moving these will work as expected:
(custom-set-variables
'(inhibit-startup-screen t)|
'(initial-scratch-message "")
'(scroll-bar-mode nil)
'(show-paren-mode t)
'(tool-bar-mode nil)
'(menu-bar-mode nil))
DEL will delete the preceding comment in this situation:
(bar)
;; bar
|(baz)
add-advice
, cl-defun
and define-derived-mode
.lispy-command-name-face
iedit
) now also works from left parenlispy-occur
. Halfway through implementinghelm-swoop
restricted to current defun.lispy-unbind-variable
.See screencast for the detailed demo of these two features.
pop-tag-mark
(was lispy-describe
). Now thelispy-describe
(was unbound).Published by abo-abo almost 10 years ago
w/s now works even if the next symbol isn't a list
(foo |(bar) baz)
->s->
(foo baz |(bar))
C-k now considers braces and brackets in addition to parens
no more compilation errors on Emacs-24.3
i will pretty-print Clojure better
delete-selection-mode
recenter
if it deleted a lot of textcond
branches: just aim at the cond
lispy-fill
, which will re-print current expression,fill-column
into considerationlispy-goto-mode
lispy-goto-projectile
lispy-goto-projectile
Published by abo-abo almost 10 years ago
"
(lispy-quote
) doesn't add extra space when at eolC-k
will not delete in one case instead of killingC-7
(lispy-cursor-down
) deactivates itselfp
(lispy-eval-other-window
) does a setq
when asked to eval thelet
statementxf
(lispy-flatten
) gives a warning when trying to extract bodyxr
(lispy-eval-and-replace
) ends in special nowr
(lispy-raise
) obeys prefix arg, i.e. 2r
, 3r
does what youC-4
(previously synonym for x
- lispy-x
) is now just aC-4 ?
are given for freem
now takes a prefix arg, e.g. 2m
will mark the second elementxj
now calls lispy-debug-step-in
M-.
now calls lispy-goto-symbol
M-,
now calls pop-tag-mark
(reverse of M-,
)Published by abo-abo almost 10 years ago
oj
, ok
, oh
and ol
will no longer select region if it wasn't selected beforei
can now handle Clojure's lambda syntaxxd
will not move the point in case of failureo
will work with multiple-cursors
E
now supports pretty-printing for Clojure (use 2E
for that)-
will mark the first part of the symbol if only one symbol is selected