Fork me on GitHub

@limix If the struggle is too real, then you can also just re-use that macro with the :macroexpand hook :) It usually helps me to put a println with the new-nodeto debug the resulting node


E.g. when I lint:

(ns bar
  (:require [foo :as foo]))

 [itm idx [1 2 3]]
then I see <list: (let [itm idx])>as the expansion and I get an unresolved idxbecause that's the right value which is referring to something unknown.


@limix So this implementation works:

(defn for-indexed [{:keys [:node]}]

  (let [[bindings & body] (-> node :children rest)
        [item index coll] (:children bindings)
        new-node (api/list-node
                   (api/token-node 'for)
                   (api/vector-node [item coll])
                     (api/token-node 'let)
                     (api/vector-node [index (api/token-node 0)])
    {:node new-node}))
I'm just generating <list: (for [itm [1 2 3]] (let [idx 0] itm))> there, to keep it simple, so I'm making a let with idx bound to 0, so if you don't use this binding then clj-kondo will report the binding as unused.


Thank you for this @U04V15CAJ - I have been trying to wrap my head around this. I’ve been tweaking your solution to try to better understand how it works. I’m confused as to why the variadic form & body works and without it returns all the same finding of no item, index coll. Also, I’m using calva and I need to restart vscode to get any changes in clj-kondo. Instead now, I’ve been linting via command line and using jet (excellent tool btw) to see what’s happening. Wondering if you have tips on a better workflow for building hooks. Lastly, I am trying to use the macroexpand hook. where would I see the output of this? When I run

clj-kondo --lint src/rdd/components/recipe/recipe_editor/testing.cljs --config '{:output {:analysis true :format :edn} :linters {:for-indexed/missing-index {:level :error}} :hooks {:macroexpand {rdd.utils.for-indexed/for-indexed script/for-indexed}}}' | jet --pretty
I’m not seeing anything like you mentioned when you lint <list: (let [itm idx])> Thanks again for all the amazing work


When you use bindings & body then body is a list of expressions, else it's a single expression


(expression = node here)


you will only see output if you prn something in your macro


and if you configured it correctly


you can push a minimal repro perhaps so we know we're talking about the same thing


Note that I used & body instead of body as well