/
watching.clj
79 lines (66 loc) · 2.47 KB
/
watching.clj
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
(ns figwheel.main.watching
(:require
[clojure.java.io :as io]
[clojure.string :as string]
[nextjournal.beholder :as beholder]))
(def ^:dynamic *watcher* (atom {:watcher nil :watches {}}))
(defn stop-watchers! [watchers]
(doseq [watcher watchers]
(beholder/stop watcher)))
(defn alter-watches [{:keys [watchers watches]} f]
(stop-watchers! watchers)
(let [watches (f watches)
watchers (doall
(for [watch (vals watches)]
(let [{:keys [paths filter handler]} watch
ctx (atom {})]
(apply beholder/watch
(fn [e]
(let [file (.toFile (:path e))
e (assoc e :file file)]
(when (or (not filter)
(filter ctx e))
(swap! ctx handler e))))
paths))))]
{:watchers watchers
:watches watches}))
(defn add-watch! [watch-key watch]
(swap! *watcher* alter-watches #(assoc % watch-key watch)))
(defn remove-watch! [watch-key]
(swap! *watcher* alter-watches #(dissoc % watch-key)))
(defn stop! []
(stop-watchers! (:watchers @*watcher*)))
(defn reset-watch! []
(stop!)
(reset! *watcher* {}))
(defn running? []
(some-> *watcher* deref :watcher :thread .isAlive))
(defn join []
(some-> *watcher* deref :watcher :thread .join))
(defn throttle [millis f]
(fn [{:keys [collector] :as ctx} e]
(let [collector (or collector (atom {}))
{:keys [collecting? events]} (deref collector)]
(if collecting?
(swap! collector update :events (fnil conj []) e)
(let [events (volatile! nil)]
(swap! collector assoc :collecting? true)
(future
(try
(Thread/sleep millis) ;; is this needed now?
(swap! collector update :events (fn [evts] (vreset! events evts) nil))
(f (cons e @events))
(finally
(swap! collector assoc :collecting? false))))))
(assoc ctx :collector collector))))
(defn file-suffix [file]
(last (string/split (.getName (io/file file)) #"\.")))
(defn real-file? [file]
(and file
(.isFile file)
(not (.isHidden file))
(not (#{\. \#} (first (.getName file))))))
(defn suffix-filter [suffixes]
(fn [_ {:keys [file]}]
(and (real-file? file)
(suffixes (file-suffix file)))))