Evil smartparens
Evil smartparens is a minor mode which makes evil play nice with smartparens.
Installation
I highly recommend installing evil-smartparens through elpa.
It's available on melpa:
M-x package-install evil-smartparens
Put this in your .emacs
or init.el
:
(add-hook 'smartparens-enabled-hook #'evil-smartparens-mode)
this will turn on evil-smartparens
whenever smartparens
is
activated. This might not be what you want, as you're likely to get
some surprises when working in buffers running say markdown-mode
.
If you just want to enable evil-smartparens
in certain modes you can
do something like this:
(add-hook 'clojure-mode-hook #'evil-smartparens-mode)
Note: If you wish to be protected from introducing unbalanced pairs by
editing commands which delete regions, what you want is smartparens-strict-mode
.
Features
The goal of evil smartparens is to do what you mean, instead of just
erroring out when smartparens-strict-mode
is active.
When only smartparens-mode
is active, the only keys that are rebound
are those imitating the functionality of sp-kill-sexp
: Y
, D
and
C
.
In the examples below smartparens-strict-mode
is active, |
indicates the position of the cursor, and [
and ]
delimit the
visual selection:
Deleting text
The goal here is to just modify the region so it is safe. Most of the times this means shrinking the region.
dW
(|sp--get-pair-list-context)
And I hit dW I will see:
()
dd
(let| ((foo 1.01))
(frobnicate foo))
And I hit dd
then nothing will happen. But If I move down a line:
(let ((foo 1.01))
(fr|obnicate foo))
And I hit dd
then I will see:
(let ((foo 1.01))
)
vd
(progn
[ (foo)
(bar 'baz)
(qux (quux (corge (grault "garply")))))]
Here I have used linewise selection and sloppily selected a bunch of unbalanced text. When I hit d
I will see:
(progn
)
This is so nice when you just want to get rid of something in a let
binding.
D
D
works like sp-kill-sexp
with a universal prefix.
(let ((foo 1.01))
(-> foo |(bar baz) qux (quux corge grault) garply))
and I hit D
I will see:
(let ((foo 1.01))
(-> foo |))
(foo "|bar baz"
quux)
becomes:
(foo ""
quux)
(|foo "bar baz"
quux)
becomes
(
quux)
|(foo ""
quux)
Will kill everything.
c and y
c
works just like d
C
just like D
but also enters insert mode. y
works just like d
except it doesn't actually remove anything from the buffer.
Known limitations
Quite a bit of work is done to ensure region is OK. This means we can run into performance issues. The variable evil-smartparens-threshold
controls how large region
should be before we cop out. The most common cases should be quite fast (regions limited to the delimiters found in lisp-like languages), but the more exotic delimiters use a much slower code path. On slow computers it might make sense to decrease evil-smartparens-threshold
. In any event, it prevents checking entire files when we're copying out from emacs.
Escape hatches
The function evil-sp-override
, which by default is bound to o
, in visual-state
provides an escape hatch, out of evil-smartparens
and back to evil
, when it's called before another command.
I've also opted not to rebind r
and R
so these can also be used to get rid of stuff that would otherwise cause evil-smartparens
to barf.
Is it any good?
Yes
The demo showcases c
, with a sloppy unbalanced selection, D
(in two contexts) and dd
.
Contribute
Please send help! There is a suite of tests that I'd like you to add to whenever a bug is fixed or a new feature is added. If you don't do this I'm likely to break your code when I stumble around the codebase.
To fetch the test dependencies, install cask if you haven't already, then:
$ cd /path/to/evil-smartparens
$ cask
Run the tests with:
$ make test
License
Copyright (C) 2015 Lars Andersen
Author: Lars Andersen expez@expez.com Keywords: evil smartparens
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.