emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Better indentation for elisp


From: Thierry Volpiatto
Subject: Re: Better indentation for elisp
Date: Mon, 18 Feb 2013 21:45:42 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux)

Sergey Mozgovoy <address@hidden> writes:

> The problem
>
> Standard indentation algorithm for Emacs Lisp is not perfect in some
> respects.  For example, it fails to indent code like this:
> *
> (flet ((sum (x y)
>                 (+ x y))
>         (diff (x y)
>                (- x y)))
>   ...)
> *
> or like this:
> *
> (func-1 (or arg-1
>                 arg-2) weird-arg
>                 another-arg)
> *
> and this:
> *
> (let (var-1 var-2
>                (x 10))
>   (+ var-1 var-2))
> *
>
> SLIME indentation
>
> Those who use SLIME know that there's a contrib *slime-cl-indent*
> which does some nice job of indenting Common Lisp code.  Aside from
> some CL-specific things (like the loop macro or tagbody), SLIME
> indentation is different from that of Elisp in that it supports
> arbitrarily-nesting indentation patterns rather than simple values.
>
> For example, here's indentation spec for *case* (quoted from
> docstring for *common-lisp-indent-function*):
> /
> ... the function `case' has an indent property (4 &rest (&whole 2 &rest 1)),
> meaning:
>   * indent the first argument by 4.
>   * arguments after the first should be lists, and there may be any number
>     of them.  The first list element has an offset of 2, all the rest
>     have an offset of 2+1=3.
> /
>
>
> SLIME => Emacs Lisp
>
> I think we could just reuse some SLIME indentation ideas for Emacs
> Lisp.  The algorithm is smart enough to handle any typical Elisp
> indentation, and it is kind of a generalization of the present one.
> General idea is this: walk nested lists up not more than some depth
> limit (*lisp-indent-maximum-backtracking*) and see what head
> symbols (*car*s) of ancestor lists say about indentation.  Upper
> specs override what was said by more local ones.  Whatever the current
> indentation we have when the depth is exhausted becomes our end
> result.
>
> One thing that I found odd in SLIME indentation is that they specify
> absolute offsets (in spaces).  I don't see why such a precision might
> be really needed.. to my mind, indentation should better be specified
> in terms of number of distinguished forms, like it is implemented now
> for Elisp.  Maybe I just don't get it.
>
> So I propose the following indentation patterns, roughly:
>   
>   * any valid value for *lisp-indent-function* symprop, meaning
>     is preserved.  This includes:
>       + natural number (# of distinguished args);
>       + *defun* symbol which means to indent in defun-style;
>       + *nil* stands for "usual" indentation, i.e. indent like a
>               normal function call form;
>       + *:flat* -- new thing which tells that list should be
>               flat, no indentation for any args;
>   
>   * (*S* . (*P-1* *P-2* ... *P-N*)), where *S* is a simple pattern
>     (any of above), and all *P-i* are any other patterns (recursive
> definition).
>     *S* specifies indentation for the enclosing list. b>P-1*, ..., *P-n*
> specify
>     indentation for sublists, beginning from the second one ("first
>     function argument");
>
>   * (*S* . (*P-1* ... *P-N* &rest *P*)), same as above but *P*
>     applies to all the other sublists after *N*.
>
> So for example, we'd give indentation for the above-mentioned forms
> like this:
> *
> (put 'flet 'lisp-indent-function '(1 (:flat &rest defun)))
> (put 'let 'lisp-indent-function '(1 (:flat &rest 1)))
> (put 'cond 'lisp-indent-function '(nil &rest :flat))
> *
> (Yes, I do agree that *cond* is indented perfectly now, this was
> just for the sake of example.)
>
> What is done so far
>
> I decided to just go ahead and try to write some Elisp indentation
> machinery.
>
> Actually, it seems to work fine on my laptop for me.  I'd be happy if
> Emacs developers find my indentation actually useful and incorporate
> some of it into Emacs.
>
> If someone gets really interested in the idea of improving Emacs Lisp
> indentation, I'm always eager to share my work.

See:

http://article.gmane.org/gmane.emacs.devel/155910/match=lisp+indent+function

-- 
Thierry
Get my Gnupg key:
gpg --keyserver pgp.mit.edu --recv-keys 59F29997 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]