clj-kondo

lassemaatta 2025-05-30T10:18:15.094729Z

we have macros like (defcommand name-of-command ...), which are later referenced elsewhere using keywords (e.g., {:command :name-of-command}). I already have a hook for the macro but what I would like to add is the ability to navigate using LSP from the keyword to the macro definition location.

lassemaatta 2025-05-30T10:20:36.822399Z

the existing hook expands the macro to something like

(let [command-parameters {..}]
  (defn command-name-of-command 
     []
     ....))
and I tried naively to modify it to return something like
(let [command-parameters {..}
      unused-placeholder :name-of-command]
  (defn command-name-of-command 
     []
     ....))
but clojure-lsp doesn't seem to care about that :name-of-command

lassemaatta 2025-05-30T10:22:24.648059Z

so my question is: is this something that ought to work (and any problems are caused by bugs in my hook) or is there some fundamental reason this cannot work?

borkdude 2025-05-30T10:24:00.965329Z

I don't think this will work since lsp just sees the keyword and doesn't know what to navigate to, but maybe @ericdallo could say more about this.

lassemaatta 2025-05-30T10:26:12.573969Z

I can use something like lsp-find-references on existing literal instances of :name-of-command in my code to jump between them but it would be nice if it could also include the (defcommand name-of-command .. case in the results so I could also jump to the "definition"

lassemaatta 2025-05-30T10:27:58.168609Z

of course the easy way out would be to refactor the macro to include the keyword, but I thought maybe with some hook magic I could achieve the same without altering existing code

borkdude 2025-05-30T10:29:51.947959Z

ah so you mean lsp would find the keyword although you don't literally write this?

borkdude 2025-05-30T10:30:46.367309Z

clj-kondo does have the concept of a keyword "definition" e.g. for re-frame. So I think that could work

lassemaatta 2025-05-30T10:31:58.732809Z

yeah, lsp-find-references applied on a keyword will find all instances of the keyword and allow me to jump to them. what I would like to do is to fool clojure-lsp into thinking that (defcommand some-command-name ...) also includes :some-command-name within so that it would be included in the list of references for :some-command-name

borkdude 2025-05-30T10:32:05.786289Z

reg-keyword!: indicates that a keyword's analysis should be marked as a definition. Expects the keyword node and either true or the fully-qualified function that registered it. This can be used to implement keyword navigation for clojure-lsp

borkdude 2025-05-30T10:33:21.100959Z

yes, I think this is possible, at least clj-kondo exposes all the data that clojure-lsp needs and you should use reg-keyword! on the keyword to mark it as the definition. note that you should still use the return value of reg-keyword! and put it in the new node

borkdude 2025-05-30T10:33:33.248739Z

(the exclamation mark in the reg-keyword! function is a poor choice)

lassemaatta 2025-05-30T10:34:09.386569Z

cool, that reg-keyword! thing sounds like something I should try, thanks 🙇

ericdallo 2025-05-30T12:50:23.429109Z

yeah reg-keyword! I think is the best way here

ericdallo 2025-05-30T12:51:11.535729Z

it's what re-frame uses under the hood, that's why navigation of re-frame/reg-event! etc works

lassemaatta 2025-05-30T13:37:04.099839Z

No idea what I'm doing, but somehow I managed to get it working. Thanks gentlemen 🙇

😂 1
borkdude 2025-05-30T13:37:58.478349Z

nice!

snoe 2025-05-30T19:00:30.178019Z

Is potemkin import-vars :rename https://github.com/clj-commons/potemkin#import-vars? Just double checking in case I missed something before raising issue/pr.

(import-vars
  [clojure.walk :refer [prewalk postwalk] :rename {prewalk pre-walk}])

borkdude 2025-05-30T19:01:58.251579Z

Probably not, but feel free to post an issue (+ PR if you're up for it)

borkdude 2025-05-30T19:02:15.754509Z

Here's a prior issue that looks similar: https://github.com/clj-kondo/clj-kondo/issues/2498

borkdude 2025-05-30T19:02:33.118989Z

So maybe just add to this issue

borkdude 2025-05-30T19:03:28.725409Z

(and upvote it)