emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Common Lisp indentation bug fix/new feature


From: Lars Magne Ingebrigtsen
Subject: Common Lisp indentation bug fix/new feature
Date: Mon, 21 Nov 2011 23:26:56 +0100
User-agent: Gnus/5.110018 (No Gnus v0.18) Emacs/24.0.91 (gnu/linux)

This is how much (most? some? I haven't actually counted) Common Lisp
code found out in the world looks like:

(defun foo ()
  (loop for z from 1 upto 5
        do (princ z)
           (terpri)
           (terpri)))

That is, the statements after DO/DOING/FINALLY/etc line up so that you
can see that they are part of the same block of code.

Unfortunately, the CL indentation code does this instead:

  (loop for z from 1 upto 5
        do (princ z)
          (terpri)
          (terpri)

Now, one can adjust the indentation with `lisp-loop-forms-indentation',
so I could just increase it by 1 and things would be OK?  Nope, since 
then FINALLY would look like:

  (loop for z from 1 upto 5
        finally (princ z)
           (terpri)
           (terpri)

With the following patch (and a defcustom adjustment), we would allow
getting the desired behaviour.

The defaults don't change, though, so this wouldn't be a user-visible
change, unless the set `lisp-loop-forms-indentation' to nil.

So would it be OK to apply this, or is it too new-featurish?  I kinda
think it fixes an indentation bug...

=== modified file 'lisp/emacs-lisp/cl-indent.el'
--- lisp/emacs-lisp/cl-indent.el        2011-11-21 21:58:38 +0000
+++ lisp/emacs-lisp/cl-indent.el        2011-11-21 22:15:28 +0000
@@ -152,11 +152,26 @@
     (error t)))
 
 
+(defun common-lisp-loop-keyword-length (loop-start)
+  "Return the length of the preceding loop keyword.
+Stop looking before LOOP-START."
+  (save-excursion
+    (let ((length 0))
+      (while (and (zerop length)
+                 (> (point) loop-start))
+       (beginning-of-line)
+       (when (looking-at "^\\s-*\\(loop\\s-*\\)?\\(:?\\sw+\\|;\\)")
+         (setq length (length (match-string 2))))
+       (forward-line -1))
+      length)))
+
+
 (defun common-lisp-loop-part-indentation (indent-point state)
   "Compute the indentation of loop form constituents."
-  (let* ((loop-indentation (save-excursion
-                            (goto-char (elt state 1))
-                            (current-column))))
+  (let ((loop-indentation (save-excursion
+                           (goto-char (elt state 1))
+                           (current-column)))
+       (case-fold-search t))
     (goto-char indent-point)
     (beginning-of-line)
     (list
@@ -165,7 +180,13 @@
           ((looking-at "^\\s-*\\(:?\\sw+\\|;\\)")
            (+ loop-indentation lisp-loop-keyword-indentation))
           (t
-           (+ loop-indentation lisp-loop-forms-indentation)))
+           (+ loop-indentation
+              lisp-loop-keyword-indentation
+              (or lisp-loop-forms-indentation
+                  (1+ (common-lisp-loop-keyword-length
+                       (or (save-excursion
+                             (re-search-backward "(\\s-*loop" nil t))
+                           indent-point)))))))
      ;; Tell the caller that the next line needs recomputation, even
      ;; though it doesn't start a sexp.
      loop-indentation)))



-- 
(domestic pets only, the antidote for overdose, milk.)
  bloggy blog http://lars.ingebrigtsen.no/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]