Commits

Anonymous committed 8029811

Improve indentation in destructuring lambda-lists

Comments (0)

Files changed (2)

+2011-05-12  Didier Verna  <didier@xemacs.org>
+
+	* cl-indent.el (lisp-lambda-list-first-keyword-column):
+	* cl-indent.el (lisp-lambda-list-keyword-parameter-column): New
+	functions. Look for lambda-list keywords by sexps instead of
+	regular expressions.
+	* cl-indent.el (lisp-indent-lambda-list): Use them.
+
 2011-05-11  Norbert Koch  <viteno@xemacs.org>
 
 	* Makefile (VERSION): XEmacs package 2.23 released.
 \\)\\([ \t]\\|$\\)"
   "Regular expression matching lambda-list keywords.")
 
+;; #### NOTE: the two functions below won't handle the presence of comments
+;; correctly, although this is really a problem with FORWARD-SEXP and
+;; BACKWARD-SEXP. -- dvl
+
+(defun lisp-lambda-list-first-keyword-column (start limit)
+  "Return the column number of the first keyword in a lambda-list.
+The keyword is searched from START forward to LIMIT across s-expressions.
+Return its column number if found, or nil."
+  (save-excursion
+    (goto-char start)
+    (skip-chars-forward " \t\n")
+    (save-match-data
+      (condition-case nil
+	  (progn
+	    (while (not (looking-at lisp-indent-lambda-list-keywords-regexp))
+	      (forward-sexp)
+	      (skip-chars-forward " \t\n")
+	      (when (>= (point) limit)
+		(error 'scan-error)))
+	    (when (looking-at lisp-indent-lambda-list-keywords-regexp)
+	      (current-column)))
+	(scan-error nil)))))
+
+(defun lisp-lambda-list-keyword-parameter-column (end)
+  "Return the indentation column of a keyword parameter in a lambda-list.
+The corresponding keyword is searched from END back across s-expressions.
+If not found, return nil. Otherwise, return the appropriate column,
+according to `lisp-lambda-list-keyword-parameter-indentation' and 
+`lisp-lambda-list-keyword-parameter-alignment'."
+  (save-excursion
+    (goto-char end)
+    (forward-line -1)
+    (end-of-line)
+    (save-match-data
+      (condition-case nil
+	  (progn
+	    (backward-sexp)
+	    (while (not (looking-at lisp-indent-lambda-list-keywords-regexp))
+	      (backward-sexp))
+	    (when (looking-at lisp-indent-lambda-list-keywords-regexp)
+	      (let* ((posn (current-column))
+		     (indented-posn
+		      (+ posn
+			 lisp-lambda-list-keyword-parameter-indentation)))
+		(forward-sexp)
+		(skip-chars-forward " \t")
+		(if (eolp)
+		    indented-posn
+		  (if lisp-lambda-list-keyword-parameter-alignment
+		      (current-column)
+		    indented-posn)))))
+	(scan-error nil)))))
+
 (defun lisp-indent-lambda-list
     (indent-point sexp-column containing-form-start)
   (let (limit)
 	   (if lisp-lambda-list-keyword-alignment
 	       ;; Align to the first keyword if any, or to the beginning of
 	       ;; the lambda-list.
-	       (save-excursion
-		 (goto-char containing-form-start)
-		 (save-match-data
-		   (if (re-search-forward
-			lisp-indent-lambda-list-keywords-regexp
-			limit t)
-		       (progn
-			 (goto-char (match-beginning 0))
-			 (current-column))
-		       (1+ sexp-column))))
-	       ;; Align to the beginning of the lambda-list.
-	       (1+ sexp-column)))
+	       (or (lisp-lambda-list-first-keyword-column
+		    (1+ containing-form-start) limit)
+		   (1+ sexp-column))
+	     ;; Align to the beginning of the lambda-list.
+	     (1+ sexp-column)))
 	  (t
-	   ;; Otherwise, align to the first argument of the last lambda-list
-	   ;; keyword, the keyword itself, or the beginning of the
-	   ;; lambda-list.
-	   (save-excursion
-	     (goto-char indent-point)
-	     (forward-line -1)
-	     (end-of-line)
-	     (save-match-data
-	       (if (re-search-backward lisp-indent-lambda-list-keywords-regexp
-				       containing-form-start t)
-		   (let* ((keyword-posn
-			   (progn
-			     (goto-char (match-beginning 0))
-			     (current-column)))
-			  (indented-keyword-posn
-			   (+ keyword-posn
-			      lisp-lambda-list-keyword-parameter-indentation)))
-		     (goto-char (match-end 0))
-		     (skip-chars-forward " \t")
-		     (if (eolp)
-			 indented-keyword-posn
-			 (if lisp-lambda-list-keyword-parameter-alignment
-			     (current-column)
-			     indented-keyword-posn)))
-		   (1+ sexp-column))))))))
+	   ;; We're facing a parameter. Align as a keyword parameter if that
+	   ;; is the case, or to the beginning of the lambda-list.
+	   (or (lisp-lambda-list-keyword-parameter-column indent-point)
+	       (1+ sexp-column))))))
 
 ;; Blame the crufty control structure on dynamic scoping
 ;;  -- not on me!