[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
Re: Better indentation for elisp, Didier Verna, 2013/02/21