sponsor Vim development Vim logo Vim Book Ad

SaneCL : Quickly indents Common Lisp code and is 100% VimScript

 script karma  Rating 14/8, Downloaded by 1256    Comments, bugs, improvements  Vim wiki

created by
Eric O'Connor
script type
Bug reports or comments welcome! Email: oconnore@gmail.com

Parsing is done using a per character tokenizer. Two stacks are used to simulate a recursive parse.

<Tab> indents lines (or ranges in visual mode)
<C-\> indents the toplevel form. Or whatever is at 150[(.

To indent an entire file, do 1GVG<Tab>. This may take a while for a large file.

:CLLoadLispwords refreshes the lisp word file
:CLIndentForm indents the toplevel form
:CLIndentRange indents a range
:CLIndentLine indents a line
:CLSetWord <word> <number> sets a lispword

Customizable variables:
String :: g:CL_lispwords_file defaults to ~/lispwords.
Boolean :: g:CL_aggressive_literals defaults to 1
Boolean :: g:CL_retab_on_open defaults to 1
Integer :: g:CL_auto_zero_limit defaults to 25
List <String> :: g:CL_loop_keywords lists all known loop keywords
List <String> :: g:CL_flets lists forms to be handled similar to flet
List < List < String, Integer > > :: g:CL_auto_prefixes lists all regexp base lisp numbers.

Add <<let g:VARIABLE = VALUE >> to your ~/.vimrc to change this. For Boolean variables, 1 is true and 0 is false.

Lisp words are stored 1 per line as such:
<symbol> <lisp #>

Aggressive literals means that forms such as (:hello world), ('got milk) and (&optional var1 var2) are treated as literals. The first character of the first symbol (if it is a symbol) are tested to match [&':].

While indenting, auto prefixes iterates over each string-integer pair. If the string matches the parent (for example "def" matches "defclass", and "^[abc].*$" matches "chair"), then the associated lisp word number is used for indentation. The first match wins.
I default to: [["with-",1], ["def",2], ["make-",1], ["map",1]]

Auto zero limit was added to preserve screen real estate for long lispy symbol names. If a symbol in your program looks like "variable-that-holds-an-integer-and-is-used-for-counting", you may appreciate this setting. Any parent string longer than the limit will be handled as a lisp number zero. By default, this is 25 characters.

My lispwords file is available at: http://paste.lisp.org/display/97882
It is not complete, but might be a useful starting point.

The indentation behavior was based on a description at http://evalwhen.com/scmindent/index.html.
install details
Save to ~/.vim/ftplugins/lisp.vim, or configure a custom command in your .vimrc such as:
autocommand! BufRead *.lisp source <file_location>

Provide an empty lispwords file, or you will see an error on the first run.

rate this script Life Changing Helpful Unfulfilling 
script versions (upload new version)

Click on the package to download.

package script version date Vim version user release notes
lisp.vim 2.0 2010-04-16 6.0 Eric O'Connor Minor change - break the auto prefix loop correctly.
lisp.vim 1.9 2010-04-16 6.0 Eric O'Connor Bug fixes, and prefix based form handling.
lisp.vim 1.8 2010-03-18 6.0 Eric O'Connor Proper comment handling. Added g:CL_define_keywords to handle multi-line variable lists.
lisp.vim 1.7 2010-02-06 6.0 Eric O'Connor Macrolets, flets, labels.
lisp.vim 1.6 2010-02-06 6.0 Eric O'Connor Loop form handling.
lisp.vim 1.5 2010-02-06 6.0 Eric O'Connor + Simple vector's gave parentheses error because they weren't handled within the sharp-sign state
+ Screen stability bugs
+ Improved plug-in hygiene (b:undo_ftplugin)
+ Added an option [g:CL_aggressive_literals] to detect all forms beginning in [&:'].* as literals. Default: true
+ Default re-tabs a new lisp file. Turn off with g:CL_retab_on_open = 0
+ Changed the g:lispwords_file variable to g:CL_lispwords_file to avoid confusion.
+ Removed unused code
lisp.vim 1.4 2010-02-03 6.0 Eric O'Connor More bug fixes regarding expandtab handling. It may be beneficial to issue :retab! if you transition from expanded tabs to hard tabs.
New lines are now auto indented properly.
lisp.vim 1.3 2010-02-01 6.0 Eric O'Connor Changed the algorithm slightly so it jives better with <noexpandtab>.
Minor bug fixes:
A multi-line s-exp or string on the first line of it's parent will now indent correctly.
lisp.vim 1.2 2010-02-01 6.0 Eric O'Connor Persistent lisp words - saves on quit.
<CLSetWord defun 2> sets a lisp word.
lisp.vim 1.1 2010-01-31 6.0 Eric O'Connor Oops! Sorry to the ... 8 people that have downloaded so far.
Fixed 2 bugs:
1. When reducing indentation, the script attempted to jump to a negative column, causing the cursor to jump.
2. With <noexpandtab>, the indentation counted tabs as a single space. Corrected by adding (&tabstop-1) * the number of leading tabs to the indentation

Let me know if you find anything else wrong with it: <oconnore@gmail.com>
lisp.vim 1.0 2010-01-31 6.0 Eric O'Connor Initial upload
ip used for rating:

If you have questions or remarks about this site, visit the vimonline development pages. Please use this site responsibly.
Questions about Vim should go to the maillist. Help Bram help Uganda.
SourceForge.net Logo