Nikodemus Siivola nikodemus@random-state.net writes:
It should, but it really doesn't. Or at least it gets easily confused. Backquotes and character-read-macros screw it up royally.
Also, it could be made more dwimmish about indentation of some forms if it had an access to their arglists... ;)
James Bielman did a SLIME hack for this: http://jamesjb.com/slime/slime-indent.el
I have some reservations about Emacs indenting code differently depending on whether it's connected to Lisp and what code Lisp has loaded. But maybe it's the right thing for such an integrated system as SLIME.
Ob hyperspec... How would you feel about moving that functionality to the CL side of things? Or ar least the symbol->url mapping part of it.
How about a cool demo to show the advantage? :-)
Here's a quick primer on SLIME hacking:
Our interface for calling Lisp from Emacs is pretty easy:
(slime-eval COMMON-LISP-FORM &optional PACKAGE-NAME) => VALUE-SEXP
The COMMON-LISP-FORM gets PRIN1'd in Emacs, sent over a socket to Lisp, and then READ in the minimal SWANK-IO-PACKAGE. That means all symbols should be package-qualified. For example:
(slime-eval '(cl:length cl:*features*) "CL-USER") => 27
.. but we don't write snippets like that in practice, instead we only call external functions in the SWANK package and with literal arguments. That avoids having a bunch of CL code snippets strewn about the elisp sources.
In that example, the CL-USER package isn't used automatically, but the Lisp side can find it in swank::*buffer-package*.
So: suppose you wrote a CL function (swank:hyperdoc SYMBOL-NAME) that checks if the symbol is interned, and if so looks it up in hyperdoc and returns the URL. Then you could use `slime-eval' in Emacs to call it and pass the resulting url to `browse-url'. That'd be Emacs-integrated hyperdoc I think.
We also have another interface, which we actually prefer:
(slime-eval-async FORM PACKAGE CONTINUATION) => void
which returns immediately and does the evaluation asynchronously. When the value comes back it is passed to CONTINUATION with funcall. The basic advantage is that it won't lock up Emacs while waiting for Lisp.
When you use slime-eval-async, remember that Elisp has dynamic scope, so by default your local bindings will have disappeared when CONTINUATION gets called. For convenience we have a macro that will lexical'ify the bindings you need:
(with-lexical-bindings (var1 ... varN) body...)
Hopefully slime.el and swank.lisp have plenty of examples of all of this stuff.
Cheers, Luke