Is there a way to get the metadata of a function in SCI - specifically the line where the function is defined - from the "Host of the SCI" (My ClojureScript-Application)?
Yes:
(-> (sci/eval-string* my-ctx "#'namespace/function") meta)And is there also a way when having stored the function in an atom at the "Host of SCI"?
why would you do that?
Because I define functions in my SCI-Input from which the user can select the function they want to run now
SCI-input? I don't get it, can you maybe write/show some code?
Like I have
(register-it #(println "hello"))
(register-it #(println "you"))
(register-it #(println "wonderful"))
(register-it #(println "world"))And then the user can switch between the registered functions via a selection
And now I want to mark the currently running function in my editor
so you create anonymous functions and then store them in an atom?
Yes
and the above is done by evaluating register-it within SCI?
Yes
register-it is a sci-macro
ok, you can look at the &form argument in the macro, the location information is on there
(defn ^:sci/macro foo [&form &env x y z])Ah, so I just store it in another macro?
you don't need another macro probably, you could do it like this
(defn register-it [&form _env fn-form]
(let [loc (meta fn-form)]
`(swap! function-store (with-meta ~fn-form ~{:line (:line loc) :column (:column loc)})))) and then the function becomes a function with location metadata
Uh, that works?
Cool
And thanks for your help!
no problem
be aware that a function with metadata isn't directly callable from JS though, don't know if that is a problem
(this could be fixable in CLJS I think but doesn't work currently)
if that is a problem you could decide to store the location metadata as a JS field on the function and get it back using aget
assuming you are in JS...
And is there a way to get the line when I take a list rather than a function in the macro?
The expression is already a list
The #(...) form expands in the reader, what the macro sees is the last expression here:
cljs.user=> `#(inc %)
(fn* [p1__6__7__auto__] (cljs.core/inc p1__6__7__auto__))which is a list
Yeah, but what if I dont get an anonymous function but just a list with the expression the user wan't
Is there also a way to get the line then?
Have you actually tried this? I think I already explained it :)
I tried it with (println (meta (list 'fn* [] code))), where code is the list I get in my macro
so you want the user to write an expression without the surrounding fn form?
Yes
Sure, the list contains the metadata
Same approach
It doesn't work on non-lists
It is a list but the code above prints nil. Any idea why?
because you are not inside of a macro, you are printing the metadata of the evaluated list which is nil
But it works inside the returned code?
And is it importand if I use fn or fn*?
Got it, thanks