Source

slimv / doc / paredit.txt

Full commit
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
*paredit.txt*                   Paredit              Last Change: 20 Nov 2012

Paredit Mode for Vim                                  *paredit* *slimv-paredit*
                               Version 0.9.9

The paredit.vim plugin performs structured editing of s-expressions used in
the Lisp, Clojure, Scheme programming languages. It may come as part of Slimv
but it is also distributed separately as a standalone plugin.

|paredit-mode|               Paredit mode
|paredit-keys|               Paredit keybindings
|paredit-options|            Paredit options

===============================================================================
PAREDIT MODE                                                     *paredit-mode*

Paredit mode is a special editing mode that keeps all matched characters
(parentheses, square and curly braces, double quotes) balanced, i.e. all opening
characters have a matching closing character. Most text entering and erasing
commands try to maintain the balanced state, so no single matched character is
added or deleted, they are entered or removed in pairs.
The function takes care of strings and comments, so no parenthesis and square
bracket balancing is performed inside a string or comment.
Please note that [] and {} pairs are not balanced for Lisp filetypes, only
for Clojure and Scheme.

The idea is taken from the paredit mode of Emacs, but not all paredit.el
editing functions are implemented or behave exactly the same way as they do
in Emacs.

When you enter a '(' then a matching ')' is automatically inserted.
If needed, spaces before and/or after the '()' pair are added.

When you press ')' in insert mode then there's no need to insert a closing
parenthesis mark (it is already there), so the cursor is simply advanced past
the next closing parenthesis (then the next outer closing parenthesis, etc.).
The result of this is however that when entering text with paredit mode
you can use the same keystrokes as without paredit mode and you get the same
result. Of course you can choose to not enter the closing parenthesis (as
required without paredit mode), because it is already there.

When you are trying to delete a ')' alone then it is not possible, the cursor
is simply moved inside the list, where all regular characters can be deleted.
When the list is finally empty: '()', then the deletion of the opening '('
makes both parentheses erased at once, so the balanced state is maintained.

All the above holds for [...] and "..." character pairs.

When you are deleting multiple characters at once, e.g. deleting a whole line,
or deleting till the end of the line, etc, then the deletion logic of a single
character is iterated. This means that the whole line or the characters till
the end of the line, etc are not necessarily deleted all. Depending on the
number of open/close parentheses, square or curly braces, double quotes some
of them might be kept in order to maintain the balanced state.
For example if you press D in Normal mode to delete till the end of line
between the a and b parameters of the following Clojure function definition:

(defn myfunc [a b c] (+ a b c))
               ^--- press D here

then the closing ] as well as the last closing ) will not be deleted, because
in the list you have an ( and a [ to be matched, so the result will be:

(defn myfunc [a])

If you are deleting multiple lines, then the above process is performed for
all lines involved. If a line was not completely cleared, then it is joined
with the next line and the process continues.


Of course not all Vim commands are compatible with the paredit mode (e.g.
you can yank and paste unbalanced code snippet, or comment out an asymmetrical
part of the code), and there is also the possibility to edit the source code
with paredit mode switched off or with another editor to make it unbalanced.
When paredit mode detects that the underlying code is not balanced, then the
paredit functionality is suspended until the top level form balance is fixed.
As soon as all parens are matched, the paredit mode is automatically resumed.
Paredit needs "syntax on" to identify the syntax elements of the underlying
code, so if syntax is switched off, then paredit will not be suspended inside
comments or strings.


Slurpage and Barfage known from Emacs is also possible but in a different
fashion: you don't move the symbols but move the opening or closing parenthesis
over the symbol or a sub-list. This way you can move any symbol or sub-list
into or out of the current list. It is not possible to move the parenthesis
over its pair, so for example if you move the opening parenthesis to the right,
then it will stop at the matched closing parenthesis.


Paredit mode is set by default for .lisp, .cl, .clj, cljs, .scm and .rkt files,
but it is possible to switch it off by putting the following statement in the
.vimrc file:

    let g:paredit_mode = 0

You can enable paredit mode for other file types as well. Here is how to set
it for Arc files (meant to be added to your .vimrc file):

    au BufNewFile,BufRead *.arc call PareditInitBuffer()

Paredit is part of Slimv, but it is also distributed separately as a standalone
plugin. If you indend to use the SWANK client and/or Slimv's indentation and
syntax functions, then please install the Slimv plugin. Otherwise you may want
to install the Paredit plugin thus omitting other unnecessary files.


===============================================================================
PAREDIT KEYBINDINGS                                              *paredit-keys*

Here follows a list of paredit keybindings:


Insert Mode:

    (              Inserts '()' and moves the cursor inside. Also adds leading
                   or trailing spaces when needed.
                   Inserts '(' when inside comment or string.

    )              Moves the cursor to the next closing parenthesis mark of
                   the current list. When pressed again then moves to the next
                   outer closing parenthesis, etc, until the closing of the
                   top level form is reached.
                   Inserts ')' when inside comment or string.
                   If |g:paredit_electric_return| is on then it also re-gathers
                   electric returns when appropriate.

    [              Inserts '[]' and moves the cursor inside. Also adds leading
                   or trailing spaces when needed.
                   Inserts '[' when inside comment or string.

    ]              Moves the cursor to the next closing square bracket of the
                   current list. When pressed again then moves to the next
                   outer closing square bracket, etc, until the closing of the
                   top level form is reached.
                   Inserts ']' when inside comment or string.
                   If |g:paredit_electric_return| is on then it also re-gathers
                   electric returns when appropriate.

    {              Inserts '{}' and moves the cursor inside. Also adds leading
                   or trailing spaces when needed.
                   Inserts '{' when inside comment or string.

    }              Moves the cursor to the next closing curly brace of the
                   current list. When pressed again then moves to the next
                   outer closing curly brace, etc, until the closing of the
                   top level form is reached.
                   Inserts '}' when inside comment or string.
                   If |g:paredit_electric_return| is on then it also re-gathers
                   electric returns when appropriate.

    "              When outside of string, inserts '""' and moves the cursor
                   inside. When inside string then moves to the closing '"'.                   
                   Inserts '"' when inside comment. Also insert '"' when inside
                   string and preceded by a '\'.

    <BS>           When about to delete a (, ), [, ], or " and there are other
                   characters inside, then just skip it to the left. When
                   about to delete the opening part of the matched character
                   with nothing inside, then the whole empty list is removed.

    <Del>          When about to delete a (, ), [, ], or " and there are other
                   characters inside, then just skip it to the right. When
                   about to delete the closing part of the matched character
                   with nothing inside, then the whole empty list is removed.

    <Enter>        If |g:paredit_electric_return| is on then insert an
                   "electric return", i.e. create an empty line by inserting
                   two newline characters.
                   

Normal Mode:

    (              Finds opening '(' of the current list. Can be pressed
                   repeatedly until the opening of the top level form reached.

    )              Finds closing ')' of the current list. Can be pressed
                   repeatedly until the closing of the top level form reached.

    [[             Go to the start of current/previous defun.

    ]]             Go to the start of next defun.

    <Leader><      If standing on a delimiter (parenthesis or square bracket)
                   then moves it to the left by slurping or barfing the
                   s-expression to the left, depending on the direction of the
                   delimiter:
                   Pressing '<' when standing on a ')' makes the s-expression
                   to the left of the ')' going out of the current list.
                   Pressing '<' when standing on a '(' makes the s-expression
                   to the left of the '(' coming into the current list.
                   For example pressing <Leader>< at position marked with |:
                       (aaa bbb|)        --->    (aaa|) bbb
                       aaa |(bbb)        --->    |(aaa bbb)

    <Leader>>      If standing on a delimiter (parenthesis or square bracket)
                   then moves it to the right by slurping or barfing the
                   s-expression to the right, depending on the direction of the
                   delimiter:
                   Pressing '>' when standing on a '(' makes the s-expression
                   to the right of the '(' going out of the current list.
                   Pressing '>' when standing on a ')' makes the s-expression
                   to the right of the ')' coming into the current list.
                   For example pressing <Leader>< at position marked with |:
                       (aaa|) bbb        --->    (aaa bbb|)
                       |(aaa bbb)        --->    aaa |(bbb)

    <Leader>J      Join two subsequent lists or strings. The first one must end
                   before the cursor, the second one must start after the
                   cursor position.
                   For example pressing <Leader>J at position marked with |:
                       (aaa)| (bbb)      --->    (aaa |bbb)
                       "aaa"| "bbb"      --->    "aaa |bbb"

    <Leader>O      Split ("Open") current list or string at the cursor position.
                   Opposite of Join. Key O is selected because for the original
                   Vim mapping J and O are also kind of opposites.
                   For example pressing <Leader>O at position marked with |:
                       (aaa |bbb)        --->    (aaa) |(bbb)
                       "aaa|bbb"         --->    "aaa" |"bbb"

    <Leader>W      Wrap the current symbol in a pair of parentheses. The cursor
    <Leader>w(     is then positioned on the opening parenthesis, as wrapping
                   is usually done because one wants to call a function with
                   the symbol as parameter, so by pressing "a" one can enter
                   the function name right after the newly inserted "(".
                   For example pressing <Leader>W at position marked with |:
                       (aaa b|bb ccc)    --->    (aaa |(bbb) ccc)

    <Leader>w[     Wrap the current symbol in a pair of square brackets,
                   similarly to <Leader>W.
                   For example pressing <Leader>w[ at position marked with |:
                       (aaa b|bb ccc)    --->    (aaa |[bbb] ccc)

    <Leader>w{     Wrap the current symbol in a pair of curly braces,
                   similarly to <Leader>W.
                   For example pressing <Leader>w{ at position marked with |:
                       (aaa b|bb ccc)    --->    (aaa |{bbb} ccc)

    <Leader>w"     Wrap the current symbol in a pair of double quotes,
                   similarly to <Leader>W.
                   For example pressing <Leader>w" at position marked with |:
                       (aaa b|bb ccc)    --->    (aaa "bbb|" ccc)

    <Leader>S      Splice the current list into the containing list, i.e.
                   remove the opening and closing parens. Opposite of wrap.
                   For example pressing <Leader>S at position marked with |:
                       (aaa (b|bb ccc) ddd)  --->    (aaa |bbb ccc ddd)

    <Leader><Up>   Splice the current list into the containing list by deleting
                   everything backward from the cursor position up to the
                   opening paren.
                   For example pressing <Leader><Up> at position marked with |:
                       (aaa (bbb |ccc) ddd)  --->    (aaa |ccc ddd)

    <Leader><Down> Splice the current list into the containing list by deleting
                   everything forward from the cursor position up to the
                   closing paren.
                   For example pressing <Leader><Down> at position marked with |:
                       (aaa (bbb| ccc) ddd)  --->    (aaa |bbb ddd)

    <Leader>I      Raise the current symbol, i.e. replace the current list with
                   the current symbol by deleting everything else (except the
                   symbol) in the list, including the eclosing pair of parens.
                   For example pressing <Leader>I at position marked with |:
                       (aaa (b|bb ccc) ddd)  --->    (aaa |bbb ddd)

    x  or  <Del>   When about to delete a (, ), [, ], or " and there are other
                   characters inside, then just skip it to the right. When
                   about to delete the closing part of the matched character
                   with nothing inside, then the whole empty list is removed.
                   When preceded by a <count> value then delete this many
                   characters.

    X              When about to delete a (, ), [, ], or " and there are other
                   characters inside, then just skip it to the left. When
                   about to delete the opening part of the matched character
                   with nothing inside, then the whole empty list is removed.

    D              Keep deleting characters towards the end of line,
                   maintaining the balanced state, i.e. keep the number of
                   opening and closing parens the same.

    C              Same as 'D' but go to insert mode at the end.

    s              Same as 'x' but go to insert mode at the end.

    dd             Delete whole line by keeping the balanced state, i.e.
                   keep the number of opening and closing parens the same.
                   When preceded by a <count> value then delete this many
                   lines.

    <Leader>S      Same as 'dd' but go to insert mode at the end.

    d{motion}      Delete text till {motion}. Keeps text balanced, so if the
                   surrounded text contains unpaired matched characters then
                   they are not removed.

    c{motion}      Delete text till {motion} and start insert mode. Keeps text
                   balanced just like d{motion}.

    p              Put the text after the cursor with all unbalanced matched
                   characters removed.

    P              Put the text before the cursor with all unbalanced matched
                   characters removed.


Visual Mode:

    (              Finds opening '(' of the current list and selects the whole
                   list. Can be pressed repeatedly until the top level form
                   selected.

    )              Finds closing ')' of the current list and selects the whole
                   list. Can be pressed repeatedly until the top level form
                   selected.

    d              Delete the current visual selection. Keeps text balanced,
    x              so the the selection contains unpaired matched characters
    <Del>          then they are not removed.

    c              Delete the current visual selection and start insert mode.
                   Keeps text balanced just like the 'd' command.

    <Leader>W      Wrap the current visual selection in a pair of parentheses.
    <Leader>w(     The visual selection is kept.

    <Leader>w[     Wrap the current visual selection in a pair of square
                   brackets. The visual selection is kept.

    <Leader>w{     Wrap the current visual selection in a pair of curly braces.
                   The visual selection is kept.

    <Leader>w"     Wrap the current visual selection in a pair of double
                   quotes. The visual selection is kept.


Please note that if variable |g:paredit_shortmaps| is nonzero then the
following normal mode mappings don't get a <Leader> prefix, they are mapped
to existing (but infrequently used) Vim functions and instead the original Vim
functions are mapped with the <Leader> prefix:

                   <, >, J, O, W, S


Vim has many built-in mappings for manipulating s-expressions. Here follows a
list of useful commands, these are not defined by paredit.vim, they are
available even when paredit mode is switched off.

    %              Find the matching pair of the parenthesis the cursor is
                   standing on.

    d%             Delete till the matching parenthesis. Normally it is used
                   when the cursor is standing on a parenthesis (works with
                   square or curly braces as well). If not standing on a
                   parenthesis then deletes left till the first opening paren,
                   so this command may also be used to delete an s-expression
                   that is right before the cursor.

    daw            Delete a word. Can be used to delete a list element, the
                   cursor may be placed anywhere in the element.

    da(            Delete the innermost s-expression. The cursor may be placed
                   anywhere inside the s-expression.

    di(            Same as da( but does not delete the enclosing parens.


===============================================================================
PAREDIT OPTIONS                                               *paredit-options*

|g:paredit_electric_return|  If nonzero, electric return feature is enabled.

|g:paredit_smartjump|        If nonzero, '(' and ')' also target square brackets
                             and curly braces when editing Clojure or Scheme.

|g:paredit_leader|           Custom <Leader> setting for Paredit.

|g:paredit_matchlines|       Number of lines to look backward and forward
                             when checking if the current form is balanced.

|g:paredit_mode|             If nonzero, paredit mode is switched on.

|g:paredit_shortmaps|        If nonzero, paredit is remapping some one-letter
                             Vim commands that are not frequently used.


                                                    *g:paredit_electric_return*
If nonzero then "electric return" feature is enabled. This means that when an
<Enter> is pressed before a closing paren in insert mode, paredit will actually
insert two newlines creating an empty line. The extra newline is consumed at
pressing the next closing paren. This feature allows linewise editing of the
subform entered in the next (empty) line.
In other words <Enter> "opens" parenthetical expressions while editing, ')'
"closes" them.
Please note that electric return is disabled for the REPL buffer if Slimv
option |g:slimv_repl_simple_eval| is nonzero. In this case <Enter> is used
to send the command line to the swank server for evaluation.

Please find a video demonstration of the electric return feature here:
http://img8.imageshack.us/img8/9479/openparen.gif

                                                          *g:paredit_smartjump*
If nonzero, this option changes the behavior of '(' and ')' in normal and visual
modes when editing Clojure or Scheme. Rather than jumping to nearest open or close
parenthesis, instead the cursor will jump to the nearest '(', '[', or '{' if
you press '(', and it will jump to the nearest ')', ']', or '}' if you press
')'. This option makes it much easier to navigate nested Clojure data
structures. It does nothing if the filetype is not clojure or Scheme.

                                                             *g:paredit_leader*
This option allows a custom <Leader> setting for the Paredit keybindings.
By default it has the same value as |mapleader|. If neither g:paredit_leader
nor mapleader are defined then the default <Leader> is "," in Paredit.
Example:
    let g:paredit_leader = '\'
If this is set in the .vimrc then Wrap will be mapped to \W instead of ,W.

There is a separate |g:slimv_leader| option for the general Slimv keybindings.

                                                         *g:paredit_matchlines*
Number of lines to look backward and forward when checking if the current
top level form is balanced in paredit mode. Default is 100.

                                                               *g:paredit_mode*
If nonzero then paredit mode is switched on, i.e. the plugin tries to keep the
balanced state of parens. This is the default behaviour.

                                                          *g:paredit_shortmaps*
If nonzero, paredit is remapping some one-letter normal mode Vim commands that
are not frequently used. These are <, >, J, O, W, S. The original function of
these maps then can be reached via <Leader> (which is the "," character
by default in Paredit).
Otherwise these paredit functions can be reached via <Leader> maintaining the
original functions of these keys.


===============================================================================
vim:tw=80:et:wrap:ft=help:norl: