rewrite-clj

steveb8n 2022-03-20T23:22:03.323929Z

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

steveb8n 2022-03-20T23:23:05.890169Z

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

steveb8n 2022-03-20T23:23:40.578409Z

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

steveb8n 2022-03-20T23:29:54.175649Z

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

steveb8n 2022-03-21T08:28:41.530809Z

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

lread 2022-03-21T13:51:35.532469Z

Hiya @steveb8n, 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?

lread 2022-03-21T14:45:05.626019Z

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?

steveb8n 2022-03-21T23:28:08.085429Z

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

lread 2022-03-22T03:25:22.321129Z

Glad to hear it @steveb8n!