August 20, 2015 clojure racket vim

'(Vim Sexp Cheat Sheet)

There are two fantastic Vim plugins that make it delightful to edit parentheses-heavy Lisp code (e.g., Racket or Clojure). I don’t know how I lived without making much use of these for years: parentheses can be terribly unwieldy.

Install them both now if you haven’t already! And read on for the cheat sheet that makes wrangling parentheses a walk in the park.

If you don’t grok Vim yet, there is surprisingly little you need to know to get started editing a Lisp with Vim. [Read this post to get started.]

Emacs users know that what appear to be a preponderance of brackets are really hooks the editor may use to effortlessly transform the text before them. — guns (author of vim-sexp)

Emacs has been the go-to environment for Lisp hackers for years. One of its particularly compelling features is “paredit”. Vim has a paredit, too, which is used as part of the SLIMV stack. I feel that SLIMV tries to do too much to your Vim, so now I’m telling you about a lighter solution: the Sexp/SRP combo.

SRP has a short README that describes all of its mappings, and it gets you most of the way to bliss. But there are a few from Sexp that are still very handy. Unlike SRP, Sexp has a lot of documentation, in both its README and vimdoc. This guide puts together the docs from both projects into a short, memorizable cheat sheet, choosing what I feel are the simplest/best set. These mostly avoid the troublesome Alt/Meta leader (which tpope doesn’t like much), and visual selection (sometimes a crutch). Where <leader> is still needed, I’ve just marked , (my leader) for brevity.

# Movement
()      move cursor to matching paren (same as % but easier) _[SEXP]_
[[ ]]   move cursor to top-level element _[SEXP]_
W B E   move cursor element/form-wise
# Indent
==      indent form  _[SEXP]_
=-      indent top level _[SEXP]_
=<movement>  indent whatever
# Move elements/forms around
>e <e     move element right/left
>f <f     move form right/left
<m- j h>  move elt left/right _[SEXP fast alternative]_ — but don’t use meta
<m- k l>  move elt left/right _[SEXP fast alternative]_ — but don’t use meta
# Slurpage and barfage
<( >)       slurp (push paren out wider)
>( <)       barf  (pull paren in narrower)
<m-s- H L>  slurp _[SEXP alternative]_ — but don’t use meta
<m-s- K J>  barf  _[SEXP alternative]_ — but don’t use meta
# Insertion, some with new parens
cse)     add surround form — easier than ysie)
<I >I    insert front/end — don’t use, too diff from ,i/,I
,h ,l    insert front/end _[SEXP]_
,i ,I    insert front/end, add surround form _[SEXP]_
,w ,W    insert front/end, add surround element _[SEXP]_
# Deletion
dsf      delete form (splice ,@)
daf dif  delete around/in form
,o       delete outer form _[SEXP]_

Note that SRP builds off of another of tpope’s concepts: Surround. That’s a good one to install and learn for any type of editing.

I struggled with these for many hours. The slurp and barf are especially hard to get your head around, so be patient. Get a simple function to experiment with, and add some extra spacing to make forms/elements stand apart. Then try out every mapping listed above.

You probably also want to install Repeat.

Also read this answer for more info on using Vim to edit Lisp.

Caveats

  • inline comments can get in the way

  • undo is funky since some commands do multiple things

Demo

Similar to the Emacs Wiki Cheat Sheet. But this is way better than Emacs’ paredit where various things are mapped to arrow keys, forcing an atrocious hand move. Oh, for shame.

You need to actually try these…​ a lot. But to give you an idea, see below. The ^ is where your cursor is. The is where your cursor is in _insert mode.

(aaa bbb)
        ^       (
(aaa bbb)
^
(aaa bbb)
      ^         <e
(bbb aaa)
(aaa bbb) (ccc ddd)
      ^                 >f
(ccc ddd) (aaa bbb)
((aaa bbb) ccc)
       ^                >)  slurp
((aaa bbb ccc))
((aaa bbb) ccc)
   ^                    <)  barf
((aaa) bbb ccc)
(aaa bbb) (ccc ddd)
            ^           yss)
((aaa bbb) (ccc ddd))
(aaa bbb)
      ^         <I  insert
(_ aaa bbb)
 ^
(aaa bbb)
      ^         ,i  surround and insert
(_ (aaa bbb))
 ^
(aaa bbb)
      ^         ,w  surround and insert word
(aaa (_ bbb))
      ^
(aaa (bbb ccc))
       ^        dsf
(aaa bbb ccc)
(aaa (bbb ccc))
       ^        daf
(aaa )
     ^
(aaa (bbb ccc))
       ^        ,o
(bbb ccc)
        ^