Fork me on GitHub
#rewrite-clj
<
2022-03-20
>
steveb8n23:03:03

Q: is there a way to z/replace a fn with cljc reader macros without the read-string output produced by z/sexpr?

steveb8n23:03:05

I see that zp/zprint-str can emit these forms without the read-string wrapper. I need to find a way to do this but via a z/replace

steveb8n23:03:40

maybe there’s a way to splice a node from one parse into a position in another parsed tree?

steveb8n23:03:54

one option might be to zprint the form(s) with cljc and then append them to the target file. this would work but doesn’t allow control over where the forms are added to the target file

steveb8n08:03:41

the problem I’m trying to escape is doc’d here. https://github.com/clj-commons/rewrite-clj/blob/main/doc/01-user-guide.adoc#reader-macro-chars the resulting read-string doesn’t work in cljs source

lread13:03:35

Hiya @U0510KXTU, I'm sure we can figure something out. To make sure I understand what you are trying to achieve, can you give me a small code example of source code you are trying to rewrite and what it should look like after rewritten?

lread14:03:05

I’m not sure if you are trying to replace something with a reader-macro or a reader-macro with something. You’ll let me know, but I’ll assume you want to replace something with a reader-macro. Let’s start real simple:

(require '[rewrite-clj.node :as n]
         '[rewrite-clj.parser :as p]
         '[rewrite-clj.zip :as z])

(def s "[1 2 3]")
Let’s say you want to replace 2 with #?(:clj 42 :cljs 43) . One way is to use the node API to express that reader conditional as rewrite-clj nodes:
(-> s
    z/of-string
    z/down
    z/right
    (z/replace (n/reader-macro-node [(n/token-node '?)
                                     (n/list-node [(n/keyword-node :clj)
                                                   (n/spaces 1)
                                                   (n/token-node 42)
                                                   (n/spaces 1)
                                                   (n/keyword-node :cljs)
                                                   (n/spaces 1)
                                                   (n/token-node 43)])] ))
    z/root-string)
;; => "[1 #?(:clj 42 :cljs 43) 3]"
Another way is to have the parser API convert a string to rewrite-clj nodes:
(-> s
    z/of-string
    z/down
    z/right
    (z/replace (p/parse-string "#?(:clj 42 :cljs 43)"))
    z/root-string)
;; => "[1 #?(:clj 42 :cljs 43) 3]"
Is that the kind of thing you are looking to do?

steveb8n23:03:08

@UE21H2HHD thank you! p/parse-string is exactly what I was looking for. works like a charm

lread03:03:22

Glad to hear it @U0510KXTU!