[slime-cvs] CVS slime/contrib

CVS User nsiivola nsiivola at common-lisp.net
Sun May 15 17:07:04 UTC 2011


Update of /project/slime/cvsroot/slime/contrib
In directory common-lisp.net:/tmp/cvs-serv1189/contrib

Modified Files:
	ChangeLog slime-cl-indent.el 
Log Message:
slime-indentation: better defmethod and lambda-list indentation

  From Didier Verna's patch sent to GNU Emacs mailing list.

   * cl-indent.el: Advertise the changes and remove obsolete TODO entries.
   * cl-indent.el (lisp-lambda-list-keyword-alignment):
   * cl-indent.el (lisp-lambda-list-keyword-parameter-indentation):
   * cl-indent.el (lisp-lambda-list-keyword-parameter-alignment): New
     customizable user options.
   * cl-indent.el (lisp-indent-defun-method): Improve docstring.
   * cl-indent.el (extended-loop-p): Fix comment.
   * cl-indent.el (lisp-indent-lambda-list-keywords-regexp): New
     variable.
   * cl-indent.el (lisp-indent-lambda-list): New function.
   * cl-indent.el (lisp-indent-259): Use it.
   * cl-indent.el (lisp-indent-defmethod): Support for more than one
     method qualifier and properly indent methods lambda-lists.
   * cl-indent.el: Provide a missing common-lisp-indent-function
     property for defgeneric.


--- /project/slime/cvsroot/slime/contrib/ChangeLog	2011/05/15 17:05:21	1.435
+++ /project/slime/cvsroot/slime/contrib/ChangeLog	2011/05/15 17:07:04	1.436
@@ -1,5 +1,27 @@
 2011-05-10  Nikodemus Siivola  <nikodemus at random-state.net>
 
+	slime-indentation: indentation improvements on defmethod and
+	lambda-lists for cl-indent.el by Didier Verna, from emacs-devel.
+
+	* slime-cl-indent.el: Advertise the changes and remove obsolete TODO
+        entries.
+	* slime-cl-indent.el (lisp-lambda-list-keyword-alignment):
+	* slime-cl-indent.el (lisp-lambda-list-keyword-parameter-indentation):
+	* slime-cl-indent.el (lisp-lambda-list-keyword-parameter-alignment): New
+        customizable user options.
+	* slime-cl-indent.el (lisp-indent-defun-method): Improve docstring.
+	* slime-cl-indent.el (extended-loop-p): Fix comment.
+	* slime-cl-indent.el (lisp-indent-lambda-list-keywords-regexp): New
+        variable.
+	* slime-cl-indent.el (lisp-indent-lambda-list): New function.
+	* slime-cl-indent.el (lisp-indent-259): Use it.
+	* slime-cl-indent.el (lisp-indent-defmethod): Support for more than one
+        method qualifier and properly indent methods lambda-lists.
+	* slime-cl-indent.el: Provide a missing common-lisp-indent-function
+        property for defgeneric.
+
+2011-05-10  Nikodemus Siivola  <nikodemus at random-state.net>
+
 	* slime-cl-indent.el: New file. Copy of cl-indent.el from current
 	GNU Emacs HEAD. Replaces the ancient copy previously kept as part
 	of slime-indentation.el.
--- /project/slime/cvsroot/slime/contrib/slime-cl-indent.el	2011/05/15 17:05:22	1.1
+++ /project/slime/cvsroot/slime/contrib/slime-cl-indent.el	2011/05/15 17:07:04	1.2
@@ -31,20 +31,6 @@
 ;;
 ;; (setq lisp-indent-function 'common-lisp-indent-function)
 
-;;>> TODO
-;; :foo
-;;   bar
-;; :baz
-;;   zap
-;; &key (like &body)??
-
-;; &rest 1 in lambda-lists doesn't work
-;;  -- really want (foo bar
-;;                  baz)
-;;     not (foo bar
-;;              baz)
-;;  Need something better than &rest for such cases
-
 ;;; Code:
 
 (defgroup lisp-indent nil
@@ -101,9 +87,55 @@
   :type 'integer
   :group 'lisp-indent)
 
+(defcustom lisp-lambda-list-keyword-alignment nil
+  "Whether to vertically align lambda-list keywords together.
+If nil (the default), keyworded lambda-list parts are aligned
+with the initial mandatory arguments, like this:
+
+\(defun foo (arg1 arg2 &rest rest
+            &key key1 key2)
+  #|...|#)
+
+If non-nil, alignment is done with the first keyword
+\(or falls back to the previous case), as in:
+
+\(defun foo (arg1 arg2 &rest rest
+                      &key key1 key2)
+  #|...|#)"
+  :type 'boolean
+  :group 'lisp-indent)
+
+(defcustom lisp-lambda-list-keyword-parameter-indentation 2
+  "Indentation of lambda list keyword parameters.
+See `lisp-lambda-list-keyword-parameter-alignment'
+for more information."
+  :type 'integer
+  :group 'lisp-indent)
+
+(defcustom lisp-lambda-list-keyword-parameter-alignment nil
+  "Whether to vertically align lambda-list keyword parameters together.
+If nil (the default), the parameters are aligned
+with their corresponding keyword, plus the value of 
+`lisp-lambda-list-keyword-parameter-indentation', like this:
+
+\(defun foo (arg1 arg2 &key key1 key2
+                        key3 key4)
+  #|...|#)
+
+If non-nil, alignment is done with the first parameter
+\(or falls back to the previous case), as in:
+
+\(defun foo (arg1 arg2 &key key1 key2
+                            key3 key4)
+  #|...|#)"
+  :type 'boolean
+  :group 'lisp-indent)
+
 
 (defvar lisp-indent-defun-method '(4 &lambda &body)
-  "Indentation for function with `common-lisp-indent-function' property `defun'.")
+  "Defun-like indentation method.
+This applies when the value of the `common-lisp-indent-function' property
+is set to `defun'.") 
 
 
 (defun extended-loop-p (loop-start)
@@ -217,8 +249,7 @@
     (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)'
-          ;; (Surely (0 3 1)?).
+          ;; `foo' has a path of (0 3 1) in `((a b c (d foo) f) g)'.
           (path ())
           ;; set non-nil when somebody works out the indentation to use
           calculated
@@ -381,10 +412,74 @@
          ;; Love those free variable references!!
          lisp-indent-error-function 'common-lisp-indent-function m))
 
+
+;; Lambda-list indentation is now done in LISP-INDENT-LAMBDA-LIST.
+;; See also `lisp-lambda-list-keyword-alignment',
+;; `lisp-lambda-list-keyword-parameter-alignment' and
+;; `lisp-lambda-list-keyword-parameter-indentation' -- dvl 
+
+(defvar lisp-indent-lambda-list-keywords-regexp
+  "&\\(\
+optional\\|rest\\|key\\|allow-other-keys\\|aux\\|whole\\|body\\|environment\
+\\)\\([ \t]\\|$\\)"
+  "Regular expression matching lambda-list keywords.")
+
+(defun lisp-indent-lambda-list
+    (indent-point sexp-column containing-form-start)
+  (let (limit)
+    (cond ((save-excursion
+	     (goto-char indent-point)
+	     (beginning-of-line)
+	     (skip-chars-forward " \t")
+	     (setq limit (point))
+	     (looking-at lisp-indent-lambda-list-keywords-regexp))
+	   ;; We're facing a lambda-list keyword.
+	   (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)))
+	  (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))))))))
+
 ;; Blame the crufty control structure on dynamic scoping
 ;;  -- not on me!
-(defun lisp-indent-259 (method path state indent-point
-                        sexp-column normal-indent)
+(defun lisp-indent-259 
+    (method path state indent-point sexp-column normal-indent)
   (catch 'exit
     (let ((p path)
           (containing-form-start (elt state 1))
@@ -452,8 +547,14 @@
 			(cond ((null p)
 			       (list (+ sexp-column 4) containing-form-start))
 			      ((null (cdr p))
-			       (+ sexp-column 1))
-			      (t normal-indent))))
+                               ;; Indentation within a lambda-list. -- dvl
+                               (list (lisp-indent-lambda-list
+                                      indent-point
+                                      sexp-column
+                                      containing-form-start)
+                                     containing-form-start))
+                              (t
+                               normal-indent))))
                 ((integerp tem)
                  (throw 'exit
                    (if (null p)         ;not in subforms
@@ -523,19 +624,26 @@
              path state indent-point sexp-column normal-indent)))
 
 
-(defun lisp-indent-defmethod (path state indent-point sexp-column
-				   normal-indent)
-  "Indentation function defmethod."
-  (lisp-indent-259 (if (and (>= (car path) 3)
-                            (null (cdr path))
-			    (save-excursion (goto-char (elt state 1))
-					    (forward-char 1)
-                                            (forward-sexp 3)
-                                            (backward-sexp)
-					    (looking-at ":\\|\\sw+")))
-		       '(4 4 (&whole 4 &rest 4) &body)
-		     (get 'defun 'common-lisp-indent-function))
-		   path state indent-point sexp-column normal-indent))
+;; LISP-INDENT-DEFMETHOD now supports the presence of more than one method
+;; qualifier and indents the method's lambda list properly. -- dvl
+(defun lisp-indent-defmethod
+    (path state indent-point sexp-column normal-indent)
+  (lisp-indent-259
+   (let ((nqual 0))
+     (if (and (>= (car path) 3)
+	      (save-excursion
+		(beginning-of-defun)
+		(forward-char 1)
+		(forward-sexp 2)
+		(skip-chars-forward " \t\n")
+		(while (looking-at "\\sw\\|\\s_")
+		  (incf nqual)
+		  (forward-sexp)
+		  (skip-chars-forward " \t\n"))
+		(> nqual 0)))
+         (append '(4) (make-list nqual 4) '(&lambda &body))
+	 (get 'defun 'common-lisp-indent-function)))
+   path state indent-point sexp-column normal-indent))
 
 
 (defun lisp-indent-function-lambda-hack (path state indent-point
@@ -577,6 +685,7 @@
            (define-modify-macro (4 &lambda &body))
            (defsetf     (4 &lambda 4 &body))
            (defun       (4 &lambda &body))
+	   (defgeneric  (4 &lambda &body))
            (define-setf-method . defun)
            (define-setf-expander . defun)
            (defmacro . defun)





More information about the slime-cvs mailing list