-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathxrepl.fnl
More file actions
86 lines (69 loc) · 2.29 KB
/
xrepl.fnl
File metadata and controls
86 lines (69 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
(local sn (require :supernova))
(local xrepl {})
(fn xrepl.extract-from [debug-fn scope]
(local to-bind {})
(var done? false)
(var index 1)
(while (and scope (not done?))
(local (success key value) (pcall debug-fn scope index))
(if (not success)
(set done? true)
(if (not= key nil)
(when (not (string.find key "^%(")) (tset to-bind key value))
(set done? true)))
(set index (+ index 1)))
to-bind)
(fn xrepl.scope-fn-at [index]
(let [info (debug.getinfo index :f)]
(when info (. info :func))))
(fn xrepl.extract []
(local keys [])
(local to-bind {})
(var i 1)
(while (< i 100)
(each [key value (pairs (xrepl.extract-from debug.getlocal i))]
(when (= (. to-bind key) nil) (table.insert keys key))
(tset to-bind key value))
(each [key value (pairs (xrepl.extract-from debug.getupvalue (xrepl.scope-fn-at i)))]
(when (= (. to-bind key) nil) (table.insert keys key))
(tset to-bind key value))
(set i (+ i 1)))
to-bind)
(fn xrepl.relevant-source? [source]
(and
(> source.line 0)
(or (string.find source.short-path "%.fnl$")
(string.find source.short-path "%.lua$"))
(not (string.find source.short-path "xrepl%.fnl$"))))
(fn xrepl.reverse [list]
(let [result []]
(var i (length list))
(while (> i 0)
(table.insert result (. list i))
(set i (- i 1)))
result))
(fn xrepl.traceback []
(local sources [])
(var i 1)
(while (< i 10)
(let [info (debug.getinfo i)]
(if info
(let [source { :short-path info.short_src :line info.currentline}]
(when (xrepl.relevant-source? source) (table.insert sources source))
(set i (+ i 1)))
(set i (+ 1 1000)))))
(xrepl.reverse sources))
(fn xrepl.print-source! [source]
(print (.. (sn.yellow source.short-path) ":" (sn.cyan source.line))))
(fn xrepl.bind! [?to-bind]
(let [fennel (require :fennel)
original-repl fennel.repl
env _G
to-bind (or ?to-bind {})]
(set debug.traceback fennel.traceback)
(each [key value (pairs (xrepl.extract))] (tset env key value))
(each [key value (pairs to-bind)] (tset env key value))
(each [_ source (pairs (xrepl.traceback))]
(xrepl.print-source! source))
(original-repl {:env env})))
xrepl.bind!