I was wondering if it is possible to specify indentation rules for all symbols that match a substring.
I have a macro that creates implicit MACROLET bodies for symbols starting with "X!" (like DEFMACRO! from Let Over Lambda), and I'd like them to be indented as LAMBDA. So, something like:
(defun/xml (item) (x!xsl/output (:method "xml")) (x!xsl/match (:name item) (x!name () (x!xsl/value-of (:select "name")))))
Currently with slime-indentation, it gets indented as such:
(defun/xml (item) (x!xsl/output (:method "xml")) (x!xsl/match (:name item) (x!name () (x!xsl/value-of (:select "name")))))
The names of symbols will not be known beforehand, just that they start with "X!".
On Thu, Oct 10, 2013 at 2:07 AM, Lucien Pullen drurowin@gmail.com wrote:
I was wondering if it is possible to specify indentation rules for all symbols that match a substring.
I don't think this is possible out of the box, but it seems like a useful feature that could be added to the slime-indentation contrib.
Have a look at the `common-lisp-get-indentation' function in slime/contrib/slime-cl-indent.el. It supports 3 methods for looking up indentation information. This is the place where you could add a 4th if you want to do it on the Emacs Lisp side.
slime/contrib/swank-indentation.lisp also has a customization mechanism as well, *application-hints-tables*, which might be useful if you want to do it on the Common Lisp side.
HTH,
Also sprach Luís Oliveira on 2013-10-11:
slime/contrib/swank-indentation.lisp also has a customization mechanism as well, *application-hints-tables*, which might be useful if you want to do it on the Common Lisp side.
I've made a modification to swank-indentation.lisp to allow functions to be called to get the indentation rule, but I've run into a bit of a snag... The indentation rule will be used when the form is the first form that needs to be looked up from *application-hints-table*.
Indentation now works like this (when given the rule (AS LAMBDA)):
(defun test () (x!html () (x!head () ...) ...))
I assume this has something to do with the way symbols are looked up, but I'm not sure where things get lost. Any pointer in the right direction will be appreciated.
On Mon, Oct 14, 2013 at 11:16 PM, Lucien Pullen drurowin@gmail.com wrote:
The indentation rule will be used when the form is the first form that needs to be looked up from *application-hints-table*.
I couldn't quite parse this sentence. What's going wrong with your current approach?
Also sprach Luís Oliveira on 2013-10-14:
On Mon, Oct 14, 2013 at 11:16 PM, Lucien Pullen drurowin@gmail.com wrote:
The indentation rule will be used when the form is the first form that needs to be looked up from *application-hints-table*.
I couldn't quite parse this sentence. What's going wrong with your current approach?
It seems that *application-hints-table* is only used once, so subsequent symbols indent like functions [and not macros]. Getting indentation for the first symbol somehow tells slime to not call swank::symbol-indentation again.
On Tue, Oct 15, 2013 at 5:42 AM, Lucien Pullen drurowin@gmail.com wrote:
It seems that *application-hints-table* is only used once, so subsequent symbols indent like functions [and not macros]. Getting indentation for the first symbol somehow tells slime to not call swank::symbol-indentation again.
That information comes from the elisp function `slime-update-system-indentation', which is only invoked by `slime-handle-indentation-update' which in turn gets triggered when SLIME gets an :INDENTATION-UPDATE message from SWANK. There seems to be some caching going on there. Can you figure out how it works?
Also sprach Luís Oliveira on 2013-10-15:
On Tue, Oct 15, 2013 at 5:42 AM, Lucien Pullen drurowin@gmail.com wrote:
It seems that *application-hints-table* is only used once, so subsequent symbols indent like functions [and not macros]. Getting indentation for the first symbol somehow tells slime to not call swank::symbol-indentation again.
That information comes from the elisp function `slime-update-system-indentation', which is only invoked by `slime-handle-indentation-update' which in turn gets triggered when SLIME gets an :INDENTATION-UPDATE message from SWANK. There seems to be some caching going on there. Can you figure out how it works?
On the SWANK side there is a function update-indentation/delta-for-emacs that handles updating the cache with symbol-indentation based on the _currently_ _interned_ symbols in the current package. That function is called often during normal typing at the REPL. The problem has nothing to do with the cache.
What has me confused is how the initial automatic macro is indented properly, before the REPL form has been read by the lisp system and the symbol interned. I know that, when defining a flet or labels SLIME will offer completion hints for those local functions when in the body of the flet or labels.
I'll look into how that is done, as well as for macrolet, tomorrow unless someone knows off the top of their head.
If this is done in the Emacs Lisp side, I assume there is a reason, other than this is a new feature, why SLIME doesn't query the lisp system [when it is connected] with the specific symbol it doesn't know about?
( The way I understand it, the ugly optimization with semantic indentation has to do with guessing correct indentation for macros defined normally instead of scanning for every macro defined. )
Also sprach Luís Oliveira on 2013-10-11:
Have a look at the `common-lisp-get-indentation' function in slime/contrib/slime-cl-indent.el. It supports 3 methods for looking up indentation information. This is the place where you could add a 4th if you want to do it on the Emacs Lisp side.
slime/contrib/swank-indentation.lisp also has a customization mechanism as well, *application-hints-tables*, which might be useful if you want to do it on the Common Lisp side.
After quickly reading each of the sources, I think adding the support in swank-indentation.lisp would be the better place.
I was thinking that modifying has-application-indentation-hint-p to accept a symbol naming a function or a function object, in addition to a hash table, that when called would return values like the current gethash calls. The author could then use their symbol test function for indentation rules in the same environment as normal use, instead of it being in the Emacs Lisp side.
This is more flexible than just accepting a subsequence, and I feel more simple to implement. The risk, since the function will be called every time symbol indentation lookup is done, is the function may be coded as to make indentation very slow or never happen, but I feel the flexibility outweighs that risk.