Index: slime.el
===================================================================
RCS file: /project/slime/cvsroot/slime/slime.el,v
retrieving revision 1.825
diff -u -r1.825 slime.el
--- slime.el	27 Aug 2007 12:55:20 -0000	1.825
+++ slime.el	27 Aug 2007 14:03:40 -0000
@@ -8672,7 +8672,7 @@
       (unless (and slime-conservative-indentation
                    (string-match "^\\(def\\|\\with-\\)" symbol-name))
         (let ((symbol (intern symbol-name))
-              (indent (cdr info)))
+              (indent (slime-clean-indent-spec (cdr info))))
           (let ((old-slime-indent (get symbol 'slime-indent)))
             (flet ((update (indent-function)
                            ;; Does the symbol have an indentation value
@@ -8685,6 +8685,16 @@
               (when (member 'scheme-mode slime-lisp-modes)
                 (update 'scheme-indent-function)))))))))
 
+(defun slime-clean-indent-spec (thing)
+  (typecase thing
+    (symbol (let* ((name (symbol-name thing))
+                   (colon-idx (position ?: name :from-end t)))
+              (if colon-idx
+                  (intern (substring name (1+ colon-idx)))
+                thing)))
+    (cons   (mapcar 'slime-clean-indent-spec thing))
+    (t      thing)))
+
 (defun slime-reindent-defun (&optional force-text-fill)
   "Reindent the current defun, or refill the current paragraph.
 If point is inside a comment block, the text around point will be
Index: swank.lisp
===================================================================
RCS file: /project/slime/cvsroot/slime/swank.lisp,v
retrieving revision 1.500
diff -u -r1.500 swank.lisp
--- swank.lisp	26 Aug 2007 23:34:50 -0000	1.500
+++ swank.lisp	27 Aug 2007 14:03:45 -0000
@@ -4675,15 +4675,15 @@
   "Return a form describing the indentation of SYMBOL.
 The form is to be used as the `common-lisp-indent-function' property
 in Emacs."
-  (if (and (macro-function symbol)
-           (not (known-to-emacs-p symbol)))
-      (let ((arglist (arglist symbol)))
-        (etypecase arglist
-          ((member :not-available)
-           nil)
-          (list
-           (macro-indentation arglist))))
-      nil))
+  (or (get symbol :emacs-indentation)
+      (when (and (macro-function symbol)
+                 (not (known-to-emacs-p symbol)))
+        (let ((arglist (arglist symbol)))
+          (etypecase arglist
+            ((member :not-available)
+             nil)
+            (list
+             (macro-indentation arglist)))))))
 
 (defun macro-indentation (arglist)
   (if (well-formed-list-p arglist)
Index: doc/slime.texi
===================================================================
RCS file: /project/slime/cvsroot/slime/doc/slime.texi,v
retrieving revision 1.55
diff -u -r1.55 slime.texi
--- doc/slime.texi	26 Aug 2007 18:42:23 -0000	1.55
+++ doc/slime.texi	27 Aug 2007 14:03:46 -0000
@@ -1044,8 +1044,22 @@
 indents these specially, putting the first arguments four spaces in and
 the ``body'' arguments just two spaces, as usual.
 
-This should ``just work.'' If you are a lucky sort of person you needn't
-read the rest of this section.
+If the @code{&body}-based heuristic does not yield satisfactory
+indentation for your macro, you can guide @SLIME{} (and, consequently,
+the Emacs indentation machinery) explicitly by setting your macro
+symbol's @code{:emacs-indentation} property to whatever you want (as
+long as it can be understood by Emacs), like this:
+
+@example
+(setf (get 'my-macro :emacs-indentation)
+      '(6 4 (&whole 2 &rest (&whole 1 &lambda &body))))
+@end example
+
+@SLIME{} will check this property and pass its value to Emacs in
+preference to the @code{&body} check.
+
+The above should ``just work.'' If you are a lucky sort of person you
+needn't read the rest of this section.
 
 To simplify the implementation, @SLIME{} doesn't distinguish between
 macros with the same symbol-name but different packages. This makes it
