Fork me on GitHub

With clojure-lsp I can use lsp-find-definition in emacs when my cursor is over a keyword, and it will jump to re-frame subscription and event definitions, or clojure specs if that makes sense. Is there a way to extend this behavior to also jump to other places that I would consider the "definition" of a keyword?

all-clear 2

sure, this is mainly done by clj-kondo, you can achive that with custom hooks


the re-frame thing is just built-in on clj-kondo but it's possible to achieve the same using clj-kondo hooks. where you would tell to clj-kondo that var is a definition


maybe @U04V15CAJ can help explaining that better, but AFAIK but if the analysis contains a :reg clojure-lsp will try to search for a var-definition that contains that the name is that :reg


Excellent. I wasn't sure if this was something special yall did in lsp or it was an extension of clj-kondo. I'll start investigating. Thanks for pointing me in the right direction.


The need started on clojure-lsp and we agreed on adding support for that on clj-kondo analysis where makes more sense :)


I may be wrong but I think clj-kondo don't expose that via hooks in any easy way :thinking_face: Checking the hooks docs I didn't find anything that could create a keyword node with a custom :reg c/c @U04V15CAJ


There is a hook function available api/reg-keyword! We haven't documented this yet as the API wasn't that stable yet, perhaps, but feel free to try it out


you can use this in places like clojure.spec or re-frame where functions register "keywords" to mean something specific like a spec or event or so


the reg-by must be a fully qualified keyword of the function which registered it


nice, I forgot about that function :) thanks!


oh look, it is documented: > :reg: can be added by :hooks using clj-kondo.hook-api/reg-keyword! to indicate a registered definition location for the keyword. It should be the fully qualified call that registered it.


So, just as an example, if I have a function that looked something like


(defn my-special-registrar [kw] ...)
And was called like so
( ::important-keyword)
Then the value of reg-by would be , as a keyword, right?


> oh look, it is documented: nice, I was looking on, the most funny is that it was me that documented that 😂


@UDVJE9RE3 can't you re-use re-frame hook for your case? since the signature looks the same


I probably could. In fact, the function in question wraps the re-frame registration events so it would be a very fitting match


like this in your .clj-kondo/config.edn

{:hooks {:analyze-call { re-frame.core/reg-event-db}}}


actually I think this should work and it looks even easier:

{:lint-as { re-frame.core/reg-event-db}}


Yeah, the lint-as was what I just tried and it works exactly as I expected.


Thank you both for your help. I'm constantly impressed by both clojure-lsp and clj-kondo. Incredible tools to work with.


The code lens references work too! That's really cool.


Thank you! :)

🙏 2
Drew Verlee17:09:37

is lsp-find-reference capable of handling ns aliases e.g (:require [ :as cat] :cat/meow would =, i feel like i saw this behavior working (which is amazing) and now i'm in a context where it isn't.

all-clear 2

You probably need to use a aliased namespaced keyword ::cat/meow right?


Otherwise :cat/meow means the namespace cat not

Drew Verlee19:09:12

your right. My example was wrong. And now when i run lsp-find-references it correctly found it, so all is well.

👍 2

I have a macro that creates two functions in a do block using defn. I’ve also created an :analyze-call hook that reproduces the same structure. When I call one of the functions the linting works correctly (i.e. I don’t get an “Unresolved symbol” error), and I can find all references to either of the generated functions. However, when I try to go to the definition of one of the functions I don’t get sent to the macro call site as I expected. Should this work, and if so, any idea what I’m doing wrong?


yes, it should work but you need to set the correct meta for the new generated nodes


otherwise the new nodes wouldn't have the :row/:col meta, making clojure-lsp ignore those analysis


Hrm, tried that but still no joy. Would the fact it’s CLJS make a difference?


not probably, can you share a repro where I could investigate? any change this code is open source?


No, unfortunately. I’ll try to create a small reproducer.

👍 2

And a related question: should “hover” show me the docstring and arglist for the generated functions?


I'm not sure about this one, maybe related with the msising meta above?