In clisp swank is unable to get arglist for macros. As a result emacs is unable to properly indent macro call, when macro has a &body parameter.
I've just developed a solution. It works for interpreted macros, but not for compiled.
Lets define two macros:
(defmacro m-with-body (a &body b) nil)
(defmacro m-without-body (a b) nil)
And then look to the macro expansion function associated with the symbols m-with-body and m-without body:
(function-lambda-expression (macro-function 'm-with-body))
(LAMBDA (SYSTEM::<MACRO-FORM> SYSTEM::<ENV-ARG>) (DECLARE (CONS SYSTEM::<MACRO-FORM>)) (DECLARE (IGNORE SYSTEM::<ENV-ARG>)) (IF (< (LIST-LENGTH-DOTTED SYSTEM::<MACRO-FORM>) 2) (SYSTEM::MACRO-CALL-ERROR SYSTEM::<MACRO-FORM>) (LET* ((A (CADR SYSTEM::<MACRO-FORM>)) (B (CDDR SYSTEM::<MACRO-FORM>))) (BLOCK M-WITH-BODY NIL)))) #(NIL NIL NIL NIL ((DECLARATION OPTIMIZE DECLARATION))) M-WITH-BODY
(function-lambda-expression (macro-function 'm-without-body))
(LAMBDA (SYSTEM::<MACRO-FORM> SYSTEM::<ENV-ARG>) (DECLARE (CONS SYSTEM::<MACRO-FORM>)) (DECLARE (IGNORE SYSTEM::<ENV-ARG>)) (IF (/= (LIST-LENGTH-DOTTED SYSTEM::<MACRO-FORM>) 3) (SYSTEM::MACRO-CALL-ERROR SYSTEM::<MACRO-FORM>) (LET* ((A (CADR SYSTEM::<MACRO-FORM>)) (B (CADDR SYSTEM::<MACRO-FORM>))) (BLOCK M-WITHOUT-BODY NIL)))) #(NIL NIL NIL NIL ((DECLARATION OPTIMIZE DECLARATION))) M-WITHOUT-BODY
Note, that variable B is bound to (CDDR SYSTEM::<MACRO-FORM>) for macro with &body argument and to (CADDR SYSTEM::<MACRO-FORM>) for macro without &body argument.
Based on this difference I've changed the arglist function in the swank-clisp.lisp file:
(defimplementation arglist (fname) (block nil (or (ignore-errors (let ((exp (function-lambda-expression fname))) (and exp (return (second exp))))) (ignore-errors (return (ext:arglist fname))) (ignore-errors (return (macro-arglist fname))) :not-available)))
(defun macro-arglist (macro-symbol) (let* ((expansion-fn (function-lambda-expression (macro-function macro-symbol))) (if-form (cadddr (cdr expansion-fn))) (let-form (cadddr if-form)) (let-vars (cadr let-form)) (arg-list nil)) (dolist (var-def let-vars) (if (char-equal (char (symbol-name (caadr var-def)) 1) #\A) (setq arg-list (append arg-list (list (car var-def)))) (setq arg-list (append arg-list (list '&body (car var-def)))))) arg-list))
Of course, this solution is implementation-tied, treats &rest and &body parameters equally and works only for interpreted code. But it works (seems to be).
I've tried this with clisp-2.34 under Windows.
Regards, -Anton