(defmacro sci-macro
"Like `defmacro` but when emitting cljs, emits a function
with &env and &form prepended to arglists and :sci/macro metadata,
so that the macro can be imported into sci using copy-var."
{:clj-kondo/lint-as 'clojure.core/defn}
[name & body]
(if (:ns &env)
(let [[doc body] (if (string? (first body))
[(first body) (rest body)]
[nil body])
[options body] (if (map? (first body))
[(first body) (rest body)]
[nil body])
arities (if (vector? (first body)) (list body) body)
arities (map (fn [[argv & body]]
(list (into '[&form &env] argv)
`(let [~'&env (assoc ~'&env :sci? true)]
~@body))) arities)]
`(defn ~(vary-meta name assoc :sci/macro true)
~@(when doc [doc])
~@(when options [options])
~@arities))
`(~'clojure.core/defmacro ~name ~@body)))