Newsgroups: comp.lang.lisp
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!news.mathworks.com!hookup!news.moneng.mei.com!howland.reston.ans.net!EU.net!uunet!franz.com!franz!smh
From: smh@Franz.COM (Steve Haflich)
Subject: Re: Prettyprinting comments with XP in CL
In-Reply-To: bane@cs.umd.edu's message of 25 Oct 1994 23:07:27 -0400
Message-ID: <SMH.94Oct26151149@vapor.Franz.COM>
Sender: news@franz.com
Nntp-Posting-Host: vapor
Organization: Franz Inc., Berkeley, CA
References: <TFB.94Oct25184148@scott.cogsci.ed.ac.uk> <38kh5f$ofg@tove.cs.umd.edu>
Date: Wed, 26 Oct 1994 22:11:49 GMT
Lines: 79

In article <38kh5f$ofg@tove.cs.umd.edu> bane@cs.umd.edu (John R. Bane) writes:

   From: bane@cs.umd.edu (John R. Bane)

   I looked into doing this about two years ago while hacking a Medley managed
   file <-> Common Lisp text file import-export package.  Doing this in general
   is hard; unless I'm missing something very basic about XP, it's nearly
   ...
   The comment-preserving reader will see this structure something like this:
   (COND ((FOO-P X) (|;| "A short comment")
	  (BAR X) (|;| "A comment that's long enough to wrap around")
	  (BAZ X)))

Here's another real hard case.  Many pprint-dispatch methods depend on
the ordering of subforms in order to indent properly.  A portable
method for DEFMETHOD might intend to indent the name, and qualifiers,
and the lambda list by 4, and then indent the body by 2, as in:

(defmethod frob :before
    ((x integer)
     (y the-name-of-a-class-constructed-to-comsume-real-estate))
  mumble
  mumble)

The standard pprint-dispatch in our implementation has many such
methods, and its hard to see how the extra comment subforms returned
by a comment-preserving reader wouldn't confuse the subform counting
that such methods necessarily do.

I really wish there were a good solution for this, because it would be
a neat thing to have.

   Anybody got a better idea?

I have _another_ idea -- I seriously doubt it's "better", only
differently ugly.

The Emacs CL code indenter, suitably extended for CL as has been the
one in the Franz Emacs-Lisp interface, is pretty smart about indenting
forms idiomatically in the presence of included comments with 1,2, or
3 semicolons.  It's also easy to write a trivial elisp program that,
say, sequences through every form of the file invoking indent-sexp at
the head of the form, or even which sequences through every line of
the file invoking lisp-indent-line.  But what it _won't_ do is insert
any line breaks.

The rough strategy would be to pprint the comment-preserved file to a
temp file, making sure at least that all comments end with a newline,
and that comments with more than one semicolon begin a new line.  The
XP pretty printer and its derivatives would still be appropriate,
since they have special knowledge about syntax (e.g. differentiating
binding lists from bodies) and would do a better first cut at
inserting idiomatic line breaks, especially where comments are
unproblematic.  Do _not_ do any special tabbing for single-semi
comments, because they confuse the printer strategies and Emacs can
take care of then later.

Then have an elisp function visit the temp file and indents it, either
form-by-form or line-by-line.  If you know elisp programming, this
isn't too difficult to write.

What this doesn't solve is treating lines that have become too long
because a single-semi comment no longer fits due to growth earlier in
the line, or double-semi comments that don't fit because their indent
point has moved rightward.  Some heuristic would need to be applied.
A single-semi comment can simply be moved to its own line, where it
will necessarily fit if it fit before the file was read.  A contiguous
block of double-semi comments could be reground by an algorithm like
this:

  Determine the block of ;; lines, and make it the current region.
  Delete the ";;" at the start of each line.
  Invoke fill-region, or one of its friends, maybe
     fill-region-as-paragraph to re-fill the text.
  Reinsert the ";;" at the start of each line.

This suggestion is offered in hope it might be helpful.  If it seems
interesting to you, I suggest lying quietly on the floor until that
feeling goes away...
