From: Tamas Papp
Subject: indenting lists (in bind, etc)
Date: 
Message-ID: <87veapf9dw.fsf@pu100877.student.princeton.edu>
SLIME indents the form below as

(bind (((really-long-variable-name-a really-long-variable-name-b
				     really-long-variable-name-c
				     really-long-variable-name-d)
	'(1 2 3 4)))
  (values really-long-variable-name-a
	  really-long-variable-name-b
	  really-long-variable-name-c
	  really-long-variable-name-d))

while semantically, I would prefer

(bind (((really-long-variable-name-a really-long-variable-name-b
	 really-long-variable-name-c really-long-variable-name-d)
   ...

Is there any way to achieve this?

Tamas

From: GP lisper
Subject: Re: indenting lists (in bind, etc)
Date: 
Message-ID: <slrnfdust3.fpf.spambait@phoenix.clouddancer.com>
On Wed, 05 Sep 2007 16:56:59 +0200, <······@gmail.com> wrote:
> SLIME indents the form below as
>
> (bind (((really-long-variable-name-a really-long-variable-name-b
> 				     really-long-variable-name-c
> 				     really-long-variable-name-d)
> 	'(1 2 3 4)))
>   (values really-long-variable-name-a
> 	  really-long-variable-name-b
> 	  really-long-variable-name-c
> 	  really-long-variable-name-d))
>
> while semantically, I would prefer
>
> (bind (((really-long-variable-name-a really-long-variable-name-b
> 	 really-long-variable-name-c really-long-variable-name-d)
>    ...
>
> Is there any way to achieve this?


It's emacs!  Of course it is achieveable ;-) Just indent the second
line the way you desire and all subsequent lines will match up.

-- 
Lisp:  Powering `Impossible Thoughts since 1958

-- 
Posted via a free Usenet account from http://www.teranews.com
From: Kent M Pitman
Subject: Re: indenting lists (in bind, etc)
Date: 
Message-ID: <ubqcgq7ce.fsf@nhplace.com>
GP lisper <········@CloudDancer.com> writes:

> On Wed, 05 Sep 2007 16:56:59 +0200, <······@gmail.com> wrote:
> > SLIME indents the form below as
> >
> > (bind (((really-long-variable-name-a really-long-variable-name-b
> > 				     really-long-variable-name-c
> > 				     really-long-variable-name-d)
> > 	'(1 2 3 4)))
> >   (values really-long-variable-name-a
> > 	  really-long-variable-name-b
> > 	  really-long-variable-name-c
> > 	  really-long-variable-name-d))
> >
> > while semantically, I would prefer
> >
> > (bind (((really-long-variable-name-a really-long-variable-name-b
> > 	 really-long-variable-name-c really-long-variable-name-d)
> >    ...
> >
> > Is there any way to achieve this?
> 
> 
> It's emacs!  Of course it is achieveable ;-) Just indent the second
> line the way you desire and all subsequent lines will match up.

Indeed, that's how you do it.

Now the trick is to resist the urge to use that knowledge.

There are many style rules of Lisp indentation but one of the fundamental
meta-style rules of Lisp is to try VERY hard never to place text that's 
inside a set of parens to the left of the open paren containing it.

People who don't use Lisp are always complaining about how they hate 
counting parens, but Lispers mostly don't count parens.  They look at
the cues in the shape, and the OP is asking to violate this primary cue.

He might as well have asked: How do I write my code in a way that will
condemn any sad soul who has to read my code to meticulous paren counting?

GP Lisper's response on the "how" would be the same.  But my advice on
the "whether" would be, too:  No, don't.

Incidentally, there's no problem in the case of the values expression
up there.  It's just the 
 (((long-foo
 long-bar)))
you want to avoid unless you absolutely have to.  And the example cited
doesn't seem to get across such an absolute need.

It is right that Emacs manual editing exists to help you around the rules
in an extreme case.  But the question wasn't about that.  It was about how
to do this indentation style systematically... and, systematically, there
are very good reasons the rules are as they are.
From: Tamas Papp
Subject: Re: indenting lists (in bind, etc)
Date: 
Message-ID: <87r6lbgalz.fsf@pu100877.student.princeton.edu>
Kent M Pitman <······@nhplace.com> writes:

> GP lisper <········@CloudDancer.com> writes:
>
>> On Wed, 05 Sep 2007 16:56:59 +0200, <······@gmail.com> wrote:
>> > SLIME indents the form below as
>> >
>> > (bind (((really-long-variable-name-a really-long-variable-name-b
>> > 				     really-long-variable-name-c
>> > 				     really-long-variable-name-d)
>> > 	'(1 2 3 4)))
>> >   (values really-long-variable-name-a
>> > 	  really-long-variable-name-b
>> > 	  really-long-variable-name-c
>> > 	  really-long-variable-name-d))
>> >
>> > while semantically, I would prefer
>> >
>> > (bind (((really-long-variable-name-a really-long-variable-name-b
>> > 	 really-long-variable-name-c really-long-variable-name-d)
>> >    ...
>> >
>> > Is there any way to achieve this?
>> 
>> 
>> It's emacs!  Of course it is achieveable ;-) Just indent the second
>> line the way you desire and all subsequent lines will match up.
>
> Indeed, that's how you do it.
>
> Now the trick is to resist the urge to use that knowledge.
>
> There are many style rules of Lisp indentation but one of the fundamental
> meta-style rules of Lisp is to try VERY hard never to place text that's 
> inside a set of parens to the left of the open paren containing it.
>
> People who don't use Lisp are always complaining about how they hate 
> counting parens, but Lispers mostly don't count parens.  They look at
> the cues in the shape, and the OP is asking to violate this primary cue.
>
> He might as well have asked: How do I write my code in a way that will
> condemn any sad soul who has to read my code to meticulous paren counting?
>
> GP Lisper's response on the "how" would be the same.  But my advice on
> the "whether" would be, too:  No, don't.
>
> Incidentally, there's no problem in the case of the values expression
> up there.  It's just the 
>  (((long-foo
>  long-bar)))
> you want to avoid unless you absolutely have to.  And the example cited
> doesn't seem to get across such an absolute need.
>
> It is right that Emacs manual editing exists to help you around the rules
> in an extreme case.  But the question wasn't about that.  It was about how
> to do this indentation style systematically... and, systematically, there
> are very good reasons the rules are as they are.

Sorry, it seems that the columns got misaligned somehow.  What I
wanted looks like

(bind (((a b
         c d) ...

instead of

(bind (((a b
           c d) ...

this time I used spaces so I hope it shows up right.  I agree with
your comment, and I am not trying to place code before the opening
paren.

The issue is more general: when indenting a function, one prefers

(foo bar baz
     aaa bbb)

but for lists,

(foo bar baz
 aaa bbb)

Of course, to determine correct indentation, one needs to know the
semantics, and I guess this is a tough problem. 

About GP Lisper's solution: it works, but I would prefer something
that stays after I reindent with M-C-q.

Tamas
From: GP lisper
Subject: Re: indenting lists (in bind, etc)
Date: 
Message-ID: <slrnfe0c60.fpf.spambait@phoenix.clouddancer.com>
On Thu, 06 Sep 2007 15:57:28 +0200, <······@gmail.com> wrote:
> Kent M Pitman <······@nhplace.com> writes:
>> GP lisper <········@CloudDancer.com> writes:
>> 
>>> It's emacs!  Of course it is achieveable ;-) Just indent the second
>>> line the way you desire and all subsequent lines will match up.
>>
>> Indeed, that's how you do it.
>>
>> Now the trick is to resist the urge to use that knowledge.

Hehe, actually I use it to fix indenting that is insufficiently 'right'.

>> People who don't use Lisp are always complaining about how they hate 
>> counting parens, but Lispers mostly don't count parens.  They look at
>> the cues in the shape, and the OP is asking to violate this primary cue.

Indeed shape is all, but your eye and my eye might not agree on
`pleasing.  I did notice the misaligned lines, and decided that tkpapp
really didn't mean that, it was likely some formating error.  I made
that decision for exactly the reason you cite, we don't count parens
-- we barely notice them, we use shape.


> Sorry, it seems that the columns got misaligned somehow.
...
> this time I used spaces so I hope it shows up right.  I agree with
> your comment, and I am not trying to place code before the opening
> paren.

I use a tougher set of rules in order that a glance will reveal
structure, I like somethings shifted more to the right, especially in
a long form.  Opening with multiple parens bothers me, since such
blocks will rarely close with multiple parens.  I use a lot of vertical
alignment for easy checking, etc.


> About GP Lisper's solution: it works, but I would prefer something
> that stays after I reindent with M-C-q.

I use the "don''t do that" answer there.  If you peel the structure
carefully first in order to adjust some centerpiece, it goes back
fine.  Adjusting a layer outside the center means adding your spacing
back.  I tend to use TAB rather than M-C-q for that, mainly because
I've modified the code and want a brief review to ensure that the mod
is placed correctly.  If the code block is under developement, then
leaving closing parens on separate lines, rather than all in a block
seems to help.  With some of those closing parens on the same line,
you indicate where multiple blocks should end rather then hunting back
thru a large group of closings.

Someday, I've decided that I will adjust the elisp rules to sharpen
them some more.  You might want to google for that, I've picked up a
couple sets over the years.


-- 
Lisp:  Powering `Impossible Thoughts since 1958

-- 
Posted via a free Usenet account from http://www.teranews.com
From: Matthias Buelow
Subject: Re: indenting lists (in bind, etc)
Date: 
Message-ID: <5kaqj6F2th0bU1@mid.dfncis.de>
Tamas Papp wrote:

> About GP Lisper's solution: it works, but I would prefer something
> that stays after I reindent with M-C-q.

I think emacs has a hardcoded special case for let/let* etc., so you're
out of luck with arbitrary let-style forms which use a different name. I
might be wrong though, I only had a quick look into this some time ago.
From: Tim X
Subject: Re: indenting lists (in bind, etc)
Date: 
Message-ID: <87wsv1yh84.fsf@lion.rapttech.com.au>
Matthias Buelow <···@incubus.de> writes:

> Tamas Papp wrote:
>
>> About GP Lisper's solution: it works, but I would prefer something
>> that stays after I reindent with M-C-q.
>
> I think emacs has a hardcoded special case for let/let* etc., so you're
> out of luck with arbitrary let-style forms which use a different name. I
> might be wrong though, I only had a quick look into this some time ago.

I think lisp-mode uses properties to control indentation. Therefore, if you
have an arbitrary form that isn't being formatted correctly and want to
set it to something, you may be able to  set the lisp-indent-function
property to achieve what you want. For example

(put 'my-let 'lisp-indent-function 2)

in a lisp-mode-hook.

I joined this thread late and the earlier posts were purged from my news
server, so if I've misunderstood the problem, apologies. 

Tim

-- 
tcross (at) rapttech dot com dot au
From: Madhu
Subject: Re: indenting lists (in bind, etc)
Date: 
Message-ID: <m3k5r18nxn.fsf@robolove.meer.net>
* Tim X <··············@lion.rapttech.com.au> :

| I think lisp-mode uses properties to control indentation. Therefore, if you
| have an arbitrary form that isn't being formatted correctly and want to
| set it to something, you may be able to  set the lisp-indent-function
| property to achieve what you want. For example
| (put 'my-let 'lisp-indent-function 2)
| in a lisp-mode-hook.

I think he may want:

(put 'bind 'common-lisp-indent-function '((&whole 4 1) &body))

[Tamas, does that work with your Emacs?]  I'm not sure whether his
LISP+SLIME combo will change that on the next `slime-update-indentation'
but it shouldn't.

Different versions of Emacs have different versions of cl-indent.el.
Consequently how some piece of code is indented is ultimately an
artifact of which Emacs was used to indent that code.

Also marking the whole buffer and doing M-x indent-buffer will result in
an indentation of the code which is slightly different from evaluating
C-M-q (indent-sexp) on each form.

This is an issue because I'd like to have my lisp code editor to indent
all my code in a canonical fashion.

| I joined this thread late and the earlier posts were purged from my news
| server, so if I've misunderstood the problem, apologies. 

--
Madhu
From: Tamas K Papp
Subject: Re: indenting lists (in bind, etc)
Date: 
Message-ID: <5kfk60F3ftv6U1@mid.individual.net>
On Sat, 08 Sep 2007 15:43:40 +0530, Madhu wrote:

> * Tim X <··············@lion.rapttech.com.au> :
> 
> | I think lisp-mode uses properties to control indentation. Therefore,
> if you | have an arbitrary form that isn't being formatted correctly and
> want to | set it to something, you may be able to  set the
> lisp-indent-function | property to achieve what you want. For example |
> (put 'my-let 'lisp-indent-function 2) | in a lisp-mode-hook.
> 
> I think he may want:
> 
> (put 'bind 'common-lisp-indent-function '((&whole 4 1) &body))
> 
> [Tamas, does that work with your Emacs?]  I'm not sure whether his
> LISP+SLIME combo will change that on the next `slime-update-indentation'
> but it shouldn't.

Sorry, it doesn't work.  I have 23.0.0.1, and put the following in 
my .emacs:

(load-library "cl-indent")
(add-hook 'lisp-mode-hook
	  (lambda ()
	    (setq lisp-indent-function 'common-lisp-indent-function)
	    (put 'bind 'common-lisp-indent-function '((&whole 4 1 &body))))

but it has no effect, indentation is still


(require :metabang-bind)
(use-package :bind)

(bind (((very-long-name-a very-long-name-b very-long-name-c
			  very-long-name-d) '(1 2 3 4))))

> Also marking the whole buffer and doing M-x indent-buffer will result in
> an indentation of the code which is slightly different from evaluating
> C-M-q (indent-sexp) on each form.

I have no indent-buffer.  Strange...

> This is an issue because I'd like to have my lisp code editor to indent
> all my code in a canonical fashion.

Same here.

Thanks,

Tamas
From: Michael Livshin
Subject: Re: indenting lists (in bind, etc)
Date: 
Message-ID: <87wsv0gz59.fsf@colinux.kakpryg.net.cmm>
Tamas K Papp <······@gmail.com> writes:

> On Sat, 08 Sep 2007 15:43:40 +0530, Madhu wrote:
>
>> (put 'bind 'common-lisp-indent-function '((&whole 4 1) &body))
>> 
>> [Tamas, does that work with your Emacs?]  I'm not sure whether his
>> LISP+SLIME combo will change that on the next `slime-update-indentation'
>> but it shouldn't.
>
> Sorry, it doesn't work.  I have 23.0.0.1, and put the following in 
> my .emacs:
>
> (load-library "cl-indent")
> (add-hook 'lisp-mode-hook
> 	  (lambda ()
> 	    (setq lisp-indent-function 'common-lisp-indent-function)
> 	    (put 'bind 'common-lisp-indent-function '((&whole 4 1 &body))))
>
> but it has no effect, indentation is still
>
> (require :metabang-bind)
> (use-package :bind)
>
> (bind (((very-long-name-a very-long-name-b very-long-name-c
> 			  very-long-name-d) '(1 2 3 4))))

if you put a body in there, or tried to put the binds on the next
line, you'd see that Madhu's suggestion does have an effect, and
exactly the intended one.

what it does _not_ help with, however, is the way Emacs indents the
list of values.  looks like that cannot be helped, but you can sort of
fix the situation by putting very-long-name-{b,c,d} on the next line
-- then very-long-name-b will be right under very-long-name-a.

>> Also marking the whole buffer and doing M-x indent-buffer will result in
>> an indentation of the code which is slightly different from evaluating
>> C-M-q (indent-sexp) on each form.
>
> I have no indent-buffer.  Strange...

indent-region, not indent-buffer.  or, using the standard shortcuts:

C-x h (this marks the whole buffer)
C-M-\ (this indents the region).

>> This is an issue because I'd like to have my lisp code editor to indent
>> all my code in a canonical fashion.
>
> Same here.

we hear you, brothers, we hear you.

cheers,
--m
From: Madhu
Subject: Re: indenting lists (in bind, etc)
Date: 
Message-ID: <m38x7gxy7x.fsf@robolove.meer.net>
* Tamas K Papp <··············@mid.individual.net> :
| On Sat, 08 Sep 2007 15:43:40 +0530, Madhu wrote:
|> (put 'bind 'common-lisp-indent-function '((&whole 4 1) &body))
| Sorry, it doesn't work.

Now I'm mad!

(setq lisp-indent-maximum-backtracking 4)

(defun madhu-indent-bind (path state indent-point sexp-column normal-indent)
  (if (>= (car path) 2)
      (if (cdr path)
	  (funcall (function lisp-indent-259) '(nil)
		   path state indent-point sexp-column normal-indent)
	(+ sexp-column lisp-body-indent))
    (+ sexp-column 1)))

(put 'bind 'common-lisp-indent-function 'madhu-indent-bind)

|> Also marking the whole buffer and doing M-x indent-buffer will result in
|> an indentation of the code which is slightly different from evaluating
|> C-M-q (indent-sexp) on each form.
|
| I have no indent-buffer.  Strange...

I  meant `indent-region' of course.  No more comments on cl-indent from me!
--
Madhu :)
From: Matthias Buelow
Subject: Re: indenting lists (in bind, etc)
Date: 
Message-ID: <5kgjdlF3it0dU1@mid.dfncis.de>
Tim X wrote:

> (put 'my-let 'lisp-indent-function 2)

The lisp-indent-function property only seems to affect the indentation
relative to the particular symbol, but not within (one of) its operands.
As I said, I think lisp-mode has a hardcoded special case that
recognizes LET/LET* specifically. A bit stupid, yes, but hey, it's emacs.
From: Michael Livshin
Subject: Re: indenting lists (in bind, etc)
Date: 
Message-ID: <871wd8iebl.fsf@colinux.kakpryg.net.cmm>
Matthias Buelow <···@incubus.de> writes:

> Tim X wrote:
>
>> (put 'my-let 'lisp-indent-function 2)
>
> The lisp-indent-function property only seems to affect the
> indentation relative to the particular symbol, but not within (one
> of) its operands.

common-lisp-indent-function is smarter than lisp-indent-function, and
its associated symbol property (conveniently named
common-lisp-indent-function) allows for nice destructuring-style
specifications.  in fact, Madhu upthread gives an example for 'bind.

also, it is very much recommended to install cl-indent-patches.el
(Google will tell you where it's at, as apparently some sort of
licensing problem prevents bundling the thing with SLIME).

cheers,
--m
From: Damien Kick
Subject: Re: indenting lists (in bind, etc)
Date: 
Message-ID: <13fluq8ni7m4d7@corp.supernews.com>
Michael Livshin wrote:

> common-lisp-indent-function is smarter than lisp-indent-function, and
> its associated symbol property (conveniently named
> common-lisp-indent-function) allows for nice destructuring-style
> specifications.  in fact, Madhu upthread gives an example for 'bind.

Madhu's function to indent bind is excellent.  Thank you for that, Madhu.

> also, it is very much recommended to install cl-indent-patches.el
> (Google will tell you where it's at, as apparently some sort of
> licensing problem prevents bundling the thing with SLIME).

And thank you, Michael.  With cl-indent-patches, I finally get

(defun f (x y
           a b)
   ...)

instead of

(defun f (x y
             a b)
   ...)

Unfortunately, I'm still seeing

(with-open-file (s p
                    :direction :output)
   ...)

instead of

(with-open-file (s p
                  :direction :output)
   ...)

Does anybody have a handy fix for this?