Source

slimv-newlisp / doc / paredit.txt

Full commit
*paredit.txt*                    Slimv               Last Change: 25 Aug 2011

Paredit mode for Slimv                                *paredit* *slimv-paredit*
                               Version 0.8.6

The paredit.vim plugin performs structured editing of s-expressions used in
the Lisp or Clojure programming language.

|paredit-mode|               Paredit mode
|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.

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, .scm and .rkt files, but
it is possible to switch it out 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()

It is also possible to use the paredit mode alone, without the other parts of
Slimv. The easiest way to do it is to delete all Slimv related files from the 
ftplugin directory. If you don't intend to use Slimv's indentation and syntax
files, then you need to keep only plugin/paredit.vim.
Another way to prevent Slimv from loading by adding this to your .vimrc file:

    let g:slimv_loaded = 1

Slimv core will not be loaded but paredit will be loaded and assigned to
.lisp, .clj, .scm, etc files.


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.

    [              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.

    {              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.

    "              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.


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.

    <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)  --->    (aaa bbb ccc)

    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


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

|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_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. Slimv tries to keep the
balanced state of parens.

                                                          *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: