Fork me on GitHub
#rewrite-clj
<
2024-04-25
>
ingesol06:04:24

Is it possible to access file coordinates (line, col) when using rewrite-clj.zip/postwalk ?

👀 1
ingesol07:04:12

Context: I’m using walk to find unwanted patterns in our code, like a linter, and want to output github PR friendly output for inline code warnings

lukasz15:04:11

Yes, rewrite-clj.zip/position will give you a [line column]

👍 1
lread17:04:18

@U21QNFC5C to use rewrite-clj.zip/position you need to use a position-tracking zipper. Playing in my REPL:

(require '[rewrite-clj.zip :as z])

(def s "[:a
 :b :c 
 :d]")

(def zloc (z/of-string* s {:track-position? true}))

(z/postwalk zloc #(println (z/position %) (z/string %)))
Outputs the following:
[1 2] :a
[2 2] :b
[2 5] :c
[3 2] :d
[1 1] [:a
 :b :c 
 :d]
[1 1] [:a
 :b :c 
 :d]
As you might have guessed, the position tracking zipper tracks and updates positions as you modify nodes in your zipper. If you are not updating your zipper, you might not really need it. You can fetch row and col via metadata when not using position tracking. If we carry on from the above REPL session:
(def zloc2 (z/of-string* s))

(z/postwalk zloc2 #(println (meta (z/node %)) (z/string %)))
Outputs the following:
{:row 1, :col 2, :end-row 1, :end-col 4} :a
{:row 2, :col 2, :end-row 2, :end-col 4} :b
{:row 2, :col 5, :end-row 2, :end-col 7} :c
{:row 3, :col 2, :end-row 3, :end-col 4} :d
{:row 1, :col 1, :end-row 3, :end-col 5} [:a
 :b :c 
 :d]
{:row 1, :col 1, :end-row 3, :end-col 5} [:a
 :b :c 
 :d]

ingesol05:04:49

Thanks, folks, this is great!