From: Raymond Wiker
Subject: Re: Lisp indentation standards
Date: 
Message-ID: <861yp5tigj.fsf@raw.grenland.fast.no>
Thore B. Karlsen <········@cs.utexas.edu> writes:

> Where can I find a complete overview of what is considered "the one true
> way" to indent Lisp programs?

        www.xemacs.org or www.gnu.org. It even comes with an editor.

-- 
Raymond Wiker
·············@fast.no

From: Tim Moore
Subject: Re: Lisp indentation standards
Date: 
Message-ID: <9f681s$kao$0@216.39.145.192>
On 31 May 2001, Raymond Wiker wrote:

> Thore B. Karlsen <········@cs.utexas.edu> writes:
> 
> > Where can I find a complete overview of what is considered "the one true
> > way" to indent Lisp programs?
> 
>         www.xemacs.org or www.gnu.org. It even comes with an editor.

You have to work a bit harder to get good Common Lisp indentation; the
default lisp-indent-function gives crappy results for many Common Lisp
macros and special forms and for some forms, like if, its indentation is
appropriate for emacs lisp but not for Common Lisp.
common-lisp-indentation-function gives much better results for Common Lisp
(duh).  So (setq lisp-indent-function 'common-lisp-indent-function) in
your lisp-mode-hook.

Actually, I have a small complaint about common-lisp-indentation-function:
it insists on indenting backquoted lists as lists of data when invariably
(for me) they are code fragments.  I often end up writing macros without
the backquote initially, which is error prone and sucks.  Anyone have a
workaround?

Tim
From: ··········@questions.com
Subject: Re: Lisp indentation standards
Date: 
Message-ID: <0mmehtkm31ogmohv018t5veshqp4148dvb@4ax.com>
On 31 May 2001 20:03:08 GMT, Tim Moore <·····@herschel.bricoworks.com> wrote:

>You have to work a bit harder to get good Common Lisp indentation; the

Can someone tell me whether the free version of Lispworks for Windows gives
good Common Lisp indentation in the listener?  My first impression of it was
that the indentation seemed erratic/random.  Gradually I stopped noticing it,
but am still not sure whether it's good or erratic.
From: Pekka P. Pirinen
Subject: Re: Lisp indentation standards
Date: 
Message-ID: <ixg0d5bkmq.fsf@globalgraphics.com>
Tim Moore <·····@herschel.bricoworks.com> writes:
> Actually, I have a small complaint about common-lisp-indentation-function:
> it insists on indenting backquoted lists as lists of data when invariably
> (for me) they are code fragments.  I often end up writing macros without
> the backquote initially, which is error prone and sucks.  Anyone have a
> workaround?

It's Emacs: Hack your own and install it instead of
common-lisp-indent-function.  I've enclosed diffs and the new function
below (as a bonus, it includes a small fix for indenting fontified
buffers).
------------------------------
1,2c1
< (defun my-cl-indent-function (indent-point state)
<   ;; Pekka 04Jul96: Adapted from common-lisp-indent-function in cl-indent.el
---
> (defun common-lisp-indent-function (indent-point state)
34,35c33
<               (setq function
< 		    (downcase (buffer-substring-no-properties tem (point))))
---
>               (setq function (downcase (buffer-substring tem (point))))
79c77
<             (cond ((and (memq (char-after (1- containing-sexp)) '(?\'))
---
>             (cond ((and (memq (char-after (1- containing-sexp)) '(?\' ?\`))
82d79
< 		   ;; Pekka 04Jul96: But do indent `(...)
84c81,85
< 		  ;; Pekka 04Jul96: Exception for ",(...)" or ",@(...)" removed
---
> 		  ((or (eql (char-after (1- containing-sexp)) ?\,)
> 		       (and (eql (char-after (1- containing-sexp)) ··@)
> 			    (eql (char-after (- containing-sexp 2)) ?\,)))
> 		   ;; ",(...)" or ",@(...)"
> 		   (setq calculated normal-indent))
------------------------------
(defun my-cl-indent-function (indent-point state)
  ;; Pekka 04Jul96: Adapted from common-lisp-indent-function in cl-indent.el
  (let ((normal-indent (current-column)))
    ;; Walk up list levels until we see something
    ;;  which does special things with subforms.
    (let ((depth 0)
          ;; Path describes the position of point in terms of
          ;;  list-structure with respect to containing lists.
          ;; `foo' has a path of (0 4 1) in `((a b c (d foo) f) g)'
          (path ())
          ;; set non-nil when somebody works out the indentation to use
          calculated
          (last-point indent-point)
          ;; the position of the open-paren of the innermost containing list
          (containing-form-start (elt state 1))
          ;; the column of the above
          sexp-column)
      ;; Move to start of innermost containing list
      (goto-char containing-form-start)
      (setq sexp-column (current-column))
      ;; Look over successively less-deep containing forms
      (while (and (not calculated)
                  (< depth lisp-indent-maximum-backtracking))
        (let ((containing-sexp (point)))
          (forward-char 1)
          (parse-partial-sexp (point) indent-point 1 t)
          ;; Move to the car of the relevant containing form
          (let (tem function method)
            (if (not (looking-at "\\sw\\|\\s_"))
                ;; This form doesn't seem to start with a symbol
                (setq function nil method nil)
              (setq tem (point))
              (forward-sexp 1)
              (setq function
		    (downcase (buffer-substring-no-properties tem (point))))
              (goto-char tem)
              (setq tem (intern-soft function)
                    method (get tem 'common-lisp-indent-function))
              (cond ((and (null method)
                          (string-match ":[^:]+" function))
                     ;; The pleblisp package feature
                     (setq function (substring function
                                               (1+ (match-beginning 0)))
                           method (get (intern-soft function)
                                       'common-lisp-indent-function)))
                    ((and (null method))
                     ;; backwards compatibility
                     (setq method (get tem 'lisp-indent-function)))))
            (let ((n 0))
              ;; How far into the containing form is the current form?
              (if (< (point) indent-point)
                  (while (condition-case ()
                             (progn
                               (forward-sexp 1)
                               (if (>= (point) indent-point)
                                   nil
                                 (parse-partial-sexp (point)
                                                     indent-point 1 t)
                                 (setq n (1+ n))
                                 t))
                           (error nil))))
              (setq path (cons n path)))

            ;; backwards compatibility.
            (cond ((null function))
                  ((null method)
                   (if (null (cdr path))
                       ;; (package prefix was stripped off above)
                       (setq method (cond ((string-match "\\`def"
                                                         function)
                                           '(4 (&whole 4 &rest 1) &body))
                                          ((string-match "\\`\\(with\\|do\\)-"
                                                         function)
                                           '(4 &body))))))
                  ;; backwards compatibility.  Bletch.
                  ((eq method 'defun)
                   (setq method '(4 (&whole 4 &rest 1) &body))))

            (cond ((and (memq (char-after (1- containing-sexp)) '(?\'))
                        (not (eql (char-after (- containing-sexp 2)) ?\#)))
                   ;; No indentation for "'(...)" elements
		   ;; Pekka 04Jul96: But do indent `(...)
                   (setq calculated (1+ sexp-column)))
		  ;; Pekka 04Jul96: Exception for ",(...)" or ",@(...)" removed
                  ((eql (char-after (1- containing-sexp)) ?\#)
                   ;; "#(...)"
                   (setq calculated (1+ sexp-column)))
                  ((null method))
                  ((integerp method)
                   ;; convenient top-level hack.
                   ;;  (also compatible with lisp-indent-function)
                   ;; The number specifies how many `distinguished'
                   ;;  forms there are before the body starts
                   ;; Equivalent to (4 4 ... &body)
                   (setq calculated (cond ((cdr path)
                                           normal-indent)
                                          ((<= (car path) method)
                                           ;; `distinguished' form
                                           (list (+ sexp-column 4)
                                                 containing-form-start))
                                          ((= (car path) (1+ method))
                                           ;; first body form.
                                           (+ sexp-column lisp-body-indent))
                                          (t
                                           ;; other body form
                                           normal-indent))))
                  ((symbolp method)
                   (setq calculated (funcall method
                                             path state indent-point
                                             sexp-column normal-indent)))
                  (t
                   (setq calculated (lisp-indent-259
                                      method path state indent-point
                                      sexp-column normal-indent)))))
          (goto-char containing-sexp)
          (setq last-point containing-sexp)
          (if (not calculated)
              (condition-case ()
                   (progn (backward-up-list 1)
                          (setq depth (1+ depth)))
                (error (setq depth lisp-indent-maximum-backtracking))))))
      calculated)))
------------------------------
-- 
Pekka P. Pirinen, Global Graphics Software
If it's spam, it's a scam.  Don't do business with net abusers.
From: Dorai Sitaram
Subject: Re: Lisp indentation standards
Date: 
Message-ID: <9f69er$76l$1@news.gte.com>
In article <··································@4ax.com>,
Thore B. Karlsen  <········@cs.utexas.edu> wrote:
>On 31 May 2001 21:41:00 +0200, Raymond Wiker <·············@fast.no>
>wrote:
>
>>> Where can I find a complete overview of what is considered "the one true
>>> way" to indent Lisp programs?
>
>>        www.xemacs.org or www.gnu.org. It even comes with an editor.
>
>I want an overview. I have Emacs installed, but I don't feel like going
>through the code to see what the rules are.

The rules are the same as Vim's for indenting code with
the "lisp" option on, except that Vim recognizes
an incomplete list of "define-style" symbols.  Such a
symbol is one that, when it occurs in the function
position, causes its arguments, if these latter occur
on a subsequent line, to be indented by +2 rather than
by the length of the function symbol + 1 (which is the
default indent rule in the Lisp modes of both Emacs and
Vi). 

It is impossible to set in stone for all time which
symbols are going to be define-style (although it's a
shrewd guess -- which Emacs of course makes --
that any symbol that starts "def..." will be one of
them).  That's why Emacs allows its user to specify
them.  Vi(m) doesn't, although there is no reason it
couldn't also.  Eg,

set lispdefsymbols+=xxx,yyy

would be a neat way, well in the spirit of Vim, to
cause xxx and yyy to be indented a la define.  All Vim
needs to do is to make a hitherto hard-wired table
user-manipulable.  

--d
From: Tim Bradshaw
Subject: Re: Lisp indentation standards
Date: 
Message-ID: <nkjn17s8rha.fsf@tfeb.org>
····@goldshoe.gte.com (Dorai Sitaram) writes:

> 
> The rules are the same as Vim's for indenting code with
> the "lisp" option on, except that Vim recognizes
> an incomplete list of "define-style" symbols.  Such a
> symbol is one that, when it occurs in the function
> position, causes its arguments, if these latter occur
> on a subsequent line, to be indented by +2 rather than
> by the length of the function symbol + 1 (which is the
> default indent rule in the Lisp modes of both Emacs and
> Vi). 

But it's more complex than that

(foo x
     y)
(foo  x
      y)
(foo
 x
 y)

In fact this rule is: indent under the previous argument, and if you
are the first argument indent by 1.  This is for ordinary function
calls.  Then there are a whole bunch of things which have the first-n
arguments indented specially (often defining forms, but also
UNWIND-PROTECT sometimes &c) and finally things which affect the way
some of their subforms are indented like LABELS:

(labels ((fun (y)
           y)) 
  ...)

Not

(labels ((fun (y)
              y))
	...)

(there are two rules here - indent the body of LABELS specially, but
also indent the local function forms specially).

I've never really seen the rules written down, and I'm not sure if I
know what all of them are even.

--tim
From: Reini Urban
Subject: Re: Lisp indentation standards
Date: 
Message-ID: <9fd127$3or$5@fstgss02.tu-graz.ac.at>
Thore B. Karlsen <········@cs.utexas.edu> wrote:
: In the mean time, here is the list of words that indent two spaces
: instead of the length of the function symbol plus one. Do you see
: anything that should _definitely_ be there? It wouldn't be hard to just
: add it and submit a patch as a quick fix.

: ---
: "defun", "define", "defmacro", "set!", "lambda", "if", "case", "let",
: "flet", "let*", "letrec", "do", "do*", "define-syntax", "let-syntax",
: "letrec-syntax",
: "destructuring-bind", "defpackage", "defparameter", "defstruct",
: "deftype", "defvar", "do-all-symbols", "do-external-symbols",
: "do-symbols", "dolist", "dotimes", "ecase", "etypecase", "eval-when",
: "labels", "macrolet", "multiple-value-bind", "multiple-value-call",
: "multiple-value-prog1", "multiple-value-setq", "prog1", "progv",
: "typecase", "unless", "unwind-protect", "when",
: "with-input-from-string", "with-open-file", "with-open-stream",
: "with-output-to-string", "with-package-iterator", "define-condition",
: "handler-bind", "handler-case", "restart-bind", "restart-case",
: "with-simple-restart", "store-value", "use-value", "muffle-warning",
: "abort", "continue", "with-slots", "with-slots*", "with-accessors",
: "with-accessors*", "defclass", "defmethod", "print-unreadable-object"

rather use "with-*" to support all with-style macros. there are many more of
them, and often they tend to be very long.
-- 
Reini Urban
http://xarch.tu-graz.ac.at/acadwiki/AutoLispFaq