all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Thierry Volpiatto <thierry.volpiatto@gmail.com>
To: emacs-devel@gnu.org
Subject: Re: Better indentation for elisp
Date: Mon, 18 Feb 2013 21:45:42 +0100	[thread overview]
Message-ID: <877gm5gxl5.fsf@gmail.com> (raw)
In-Reply-To: 1361217567226-278668.post@n5.nabble.com

Sergey Mozgovoy <egnartsms@gmail.com> 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	other threads:[~2013-02-18 20:45 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-18 19:59 Better indentation for elisp Sergey Mozgovoy
2013-02-18 20:45 ` Thierry Volpiatto [this message]
2013-02-19  6:23   ` Sergey Mozgovoy
2013-02-19  6:55     ` Thierry Volpiatto
2013-02-19 13:53 ` Stefan Monnier
2013-02-19 15:41   ` João Távora
2013-02-20 14:55   ` Sergey Mozgovoy
2013-02-20 15:47     ` Stefan Monnier
2013-02-21 10:51       ` Sergey Mozgovoy
2013-02-21 15:31         ` Stefan Monnier
2013-02-21 15:54 ` Didier Verna
2013-02-24  8:29   ` Sergey Mozgovoy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=877gm5gxl5.fsf@gmail.com \
    --to=thierry.volpiatto@gmail.com \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.