hi all,
I find that sometimes the usual Slime way of determining macro indentation based on the position of the &BODY parameter in the argument list is not quite enough.
for example: if the body of a certain macro is really a list of function bindings, then one would like those bindings to be indented properly. as it happens, Emacs (or rather common-lisp-indent-function) can be told exactly how to do that, but this information cannot be expressed by the macro argument list alone.
the attached patch adds a way to define and access custom indentation specifications like this:
<example> (defmacro my-macro (name (&rest args) &body function-bindings) ...)
#+swank (setf (swank:emacs-indentation 'my-macro) '(6 4 (&whole 2 &rest (&whole 1 &lambda &body)))) </example>
[ which won't work exactly as written, of course, because unfortunately Swank does not push anything onto *FEATURES*... ]
thanks, --m
* swank.lisp (*emacs-indentation*): New hash table, used to hold custom indentation specs. (emacs-indentation): Accessor for the above. (symbol-indentation): Use it.
* slime.el (slime-clean-indent-spec): New function, removes CL package prefixes from symbols sent from Lisp. (slime-handle-indentation-update): Use it.
+ Michael Livshin gmane@cmm.kakpryg.net:
| for example: if the body of a certain macro is really a list of | function bindings, then one would like those bindings to be indented | properly. as it happens, Emacs (or rather | common-lisp-indent-function) can be told exactly how to do that, but | this information cannot be expressed by the macro argument list alone. | | the attached patch adds a way to define and access custom indentation | specifications like this: | | <example> | (defmacro my-macro (name (&rest args) &body function-bindings) | ...)
Uh, am I missing something here, or is that an inappropriate use of &body? I would use &rest in this situation. Why don't you? Of course, it would probably still not give the appropriate indentation, so emacs still needs some help. It's just that my gut reaction says that a list of function bindings is not a body, and so saying it is one seems disingenuous.
- Harald
Harald Hanche-Olsen hanche@math.ntnu.no writes:
- Michael Livshin gmane@cmm.kakpryg.net:
| <example> | (defmacro my-macro (name (&rest args) &body function-bindings) | ...)
Uh, am I missing something here, or is that an inappropriate use of &body? I would use &rest in this situation. Why don't you?
because with &REST Emacs would indent the bindings waaaay to the right (unless I put the name and args on a separate line, which is also not really plesant), so I've sort of grown used to use &BODY in such cases.
It's just that my gut reaction says that a list of function bindings is not a body, and so saying it is one seems disingenuous.
I think your gut reaction is right, if one is willing to discount the present realities of using Emacs and Slime.
thanks, --m
* Michael Livshin [2007-08-25 17:01+0200] writes:
<example> (defmacro my-macro (name (&rest args) &body function-bindings) ...)
#+swank (setf (swank:emacs-indentation 'my-macro) '(6 4 (&whole 2 &rest (&whole 1 &lambda &body))))
</example>
Can't you do that with Emacs' file local variables? E.g.
;; Local Variables: ;; eval: (set-indentation '(6 4 (&whole 2 &rest (&whole 1 &lambda &body)))) ;; End:
set-indentation is just a hypothetical name to illustrate the idea. This way we wouldn't need to put anything into *features* and the file could also be edited without connected Lisp.
Helmut.
Helmut Eller heller@common-lisp.net writes:
Can't you do that with Emacs' file local variables? E.g.
not exactly. here I'm mostly concerned with _other_ files that use the macro (indeed, at least in my code, such macros tend to _never_ be used in the file they are defined in). so to have this scheme be useful, it'd be required either to replicate the local-eval form in every file that uses the macro (or in some "<foo>-tweaks.el" file on the side, I guess), or to have the macro-defining file be open in Emacs.
This way we wouldn't need to put anything into *features*.
this was a minor point, of course.
and the file could also be edited without connected Lisp.
the present &BODY-based macro indentation logic also requires connected Lisp, so no change there.
just to be clear: the patch (if the puny little thing can even be called that) is there mostly to illustrate an idea. it's small enough for me to maintain it quite painlessly in my local checkout of Slime for the foreseeable future, so I'd hate for anyone to feel under any kind of pressure to react to this as something to be either included in Slime or not. I think it would be cool if someone came up with a better idea, really.
thanks, --m
Michael Livshin gmane@cmm.kakpryg.net writes:
the attached patch adds a way to define and access custom indentation specifications like this:
<example> (defmacro my-macro (name (&rest args) &body function-bindings) ...)
#+swank (setf (swank:emacs-indentation 'my-macro) '(6 4 (&whole 2 &rest (&whole 1 &lambda &body))))
</example>
I am also interested in a feature like this.
In my opinion, an important consideration in implementing it is that FASL files generated within SLIME should still be loadable into non-SWANK images.
I am using the following code to do that (for a different customization):
;; Arrange for SLIME to use the right readtable (when (find-package :swank) (push (cons :guile guile-internal::*guile-readtable*) (symbol-value (intern (symbol-name '#:*readtable-alist*) :swank)))
(defmethod swank-backend:swank-compile-file :around (file-name load-p) (if (string= (pathname-type file-name) "scm") (let ((*package* (find-package :guile)) (*readtable* guile-internal::*guile-readtable*)) (call-next-method)) (call-next-method))) )
Because all references to the SWANK package are made at load time (not read or compile time), FASL files including the above code can still be loaded into non-SWANK images.
A SWANK macro (SWANK:DEF-EMACS-INDENTATION?) that expands into something similar would be useful.
Matthias
* Matthias Koeppe (mkoeppe+slime@mail.math.uni-magdeburg.de) [070825 14:56]:
Michael Livshin gmane@cmm.kakpryg.net writes:
the attached patch adds a way to define and access custom indentation specifications like this:
<example> (defmacro my-macro (name (&rest args) &body function-bindings) ...)
#+swank (setf (swank:emacs-indentation 'my-macro) '(6 4 (&whole 2 &rest (&whole 1 &lambda &body))))
</example>
I am also interested in a feature like this.
In my opinion, an important consideration in implementing it is that FASL files generated within SLIME should still be loadable into non-SWANK images.
I have also wished for a feature like this on several occasions. I think it would be useful for a lot of people if something like it were included in slime.
--larry
Matthias Koeppe mkoeppe+slime@mail.math.uni-magdeburg.de writes:
In my opinion, an important consideration in implementing it is that FASL files generated within SLIME should still be loadable into non-SWANK images.
I am using the following code to do that (for a different customization):
[ snipped ]
Because all references to the SWANK package are made at load time (not read or compile time), FASL files including the above code can still be loaded into non-SWANK images.
A SWANK macro (SWANK:DEF-EMACS-INDENTATION?) that expands into something similar would be useful.
this is nice, but if you decide to already require SWANK for compilation (so that you can use the macro), you can do even better using the underappreciated CL feature called "symbol property lists" (why haven't I though of that from the start?):
<example> (setf (get 'my-macro 'swank:emacs-indentation) '(6 4 (&whole 2 &rest (&whole 1 &lambda &body)))) </example>
which has the nice property of storing the relevant information completely regardless of Swank's presence in the image at load time.
indeed, while we are at it, why require Swank for compilation? there's no technical reason to have the magic property designator reside in the Swank package: it could instead be provided by a separate small library (which would be namespace-correct, but probably too much hassle for such a small feature), or simply be the :EMACS-INDENTATION keyword (which name-conflict-concious people will surely balk at, but which is dead simple and maximally effective!).
hmm, --m
On 8/26/07, Michael Livshin gmane@cmm.kakpryg.net wrote:
<example> (setf (get 'my-macro 'swank:emacs-indentation) '(6 4 (&whole 2 &rest (&whole 1 &lambda &body)))) </example>
which has the nice property of storing the relevant information completely regardless of Swank's presence in the image at load time.
Not true: to load the symbol MY-MACRO from a fasl after this requires SWANK. Nothing gained.
Cheers,
-- Nikodemus
"Nikodemus Siivola" nikodemus@random-state.net writes:
On 8/26/07, Michael Livshin gmane@cmm.kakpryg.net wrote:
<example> (setf (get 'my-macro 'swank:emacs-indentation) '(6 4 (&whole 2 &rest (&whole 1 &lambda &body)))) </example>
which has the nice property of storing the relevant information completely regardless of Swank's presence in the image at load time.
Not true: to load the symbol MY-MACRO from a fasl after this requires SWANK. Nothing gained.
oh, right.
I like the keyword route more and more, really. those Lisp Machine people had it easy...
cheers, --m
Michael Livshin gmane@cmm.kakpryg.net writes:
using the underappreciated CL feature called "symbol property lists" [... using the ...] :EMACS-INDENTATION keyword
Can you prepare a patch (including documentation for the SLIME manual) based on this simplified idea? I'm pretty sure it can find a place in SLIME.
Matthias
Matthias Koeppe mkoeppe+slime@mail.math.uni-magdeburg.de writes:
Michael Livshin gmane@cmm.kakpryg.net writes:
using the underappreciated CL feature called "symbol property lists" [... using the ...] :EMACS-INDENTATION keyword
Can you prepare a patch (including documentation for the SLIME manual) based on this simplified idea?
sure, --m
2007-08-27 Michael Livshin slime@cmm.kakpryg.net
Allow manual indentation tuning through the :emacs-indentation symbol property.
* slime.el (slime-handle-indentation-update): Clean up the indentation spec that comes from Swank by removing any package prefixes. (slime-clean-indent-spec): ...by calling this new function. * swank.lisp (symbol-indentation): Look at the value of the :emacs-indentation property and use that if present. * doc/slime.texi: Briefly document this in the "Semantic indentation" section. Perhaps should also describe what indentation specs should look like...