Skip to content

Commit 40e9f12

Browse files
committed
Watch directory changes instead of file
This avoids problem with eg Vim which replaces the file with a temporary one (with a different file descriptor). Signed-off-by: Paul-Elliot <[email protected]>
1 parent 94ed063 commit 40e9f12

File tree

1 file changed

+43
-22
lines changed

1 file changed

+43
-22
lines changed

compiler/src/bin/native/serve.ml

+43-22
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
1-
let ( let+ ) a b = Result.bind a b
2-
31
let do_watch input f =
42
match input with
53
| `Stdin -> Error (`Msg "--watch is incompatible with stdin input")
64
| `File input ->
7-
let input = Fpath.to_string input in
5+
let parent = Fpath.parent input in
6+
let parent = Fpath.to_string parent in
7+
let input_filename = Fpath.filename input in
88
let inotify = Inotify.create () in
99
let _watch_descriptor =
10-
Inotify.add_watch inotify input [ Inotify.S_Modify ]
10+
Inotify.add_watch inotify parent [ Inotify.S_Close_write ]
1111
in
1212
let rec loop () =
13-
let _event = Inotify.read inotify in
14-
Logs.app (fun m -> m "Recompiling");
15-
let+ _ = f () in
13+
let events = Inotify.read inotify in
14+
List.iter
15+
(function
16+
| _, _, _, Some filename ->
17+
if String.equal filename input_filename then (
18+
Logs.app (fun m -> m "Recompiling");
19+
match f () with
20+
| Ok _ -> ()
21+
| Error (`Msg s) -> Logs.warn (fun m -> m "%s" s))
22+
else ()
23+
| _ -> ())
24+
events;
1625
loop ()
1726
in
1827
loop ()
@@ -21,14 +30,15 @@ let do_serve input f =
2130
let do_serve input f =
2231
match input with
2332
| `Stdin ->
24-
Lwt.return
25-
@@ Error (`Msg "--watch-and-serve is incompatible with stdin input")
33+
Lwt.return @@ Error (`Msg "--serve is incompatible with stdin input")
2634
| `File input ->
2735
let open Lwt.Syntax in
28-
let input = Fpath.to_string input in
36+
let parent = Fpath.parent input in
37+
let parent = Fpath.to_string parent in
38+
let input_filename = Fpath.filename input in
2939
let* inotify = Lwt_inotify.create () in
3040
let _watch_descriptor =
31-
Lwt_inotify.add_watch inotify input [ Inotify.S_Modify ]
41+
Lwt_inotify.add_watch inotify parent [ Inotify.S_Close_write ]
3242
in
3343
let waiter, resolver = Lwt.wait () in
3444
let waiter = ref waiter in
@@ -51,17 +61,28 @@ let do_serve input f =
5161
]
5262
in
5363
let rec loop () =
54-
let new_content = match f () with Ok s -> s | Error (`Msg s) -> s in
55-
content := new_content;
56-
let* _event = Lwt_inotify.read inotify in
57-
Logs.app (fun m -> m "Recompiling");
58-
let old_resolver = !resolver in
59-
let nwaiter, nresolver = Lwt.wait () in
60-
waiter := nwaiter;
61-
resolver := nresolver;
62-
Dream.log "Asking browsers to reload";
63-
Lwt.wakeup_later old_resolver ();
64-
loop ()
64+
let* _descriptor, _event_kinds, _, filename =
65+
Lwt_inotify.read inotify
66+
in
67+
match filename with
68+
| Some filename when String.equal filename input_filename ->
69+
Logs.app (fun m -> m "Recompiling");
70+
let new_content =
71+
match f () with
72+
| Ok s -> s
73+
| Error (`Msg s) ->
74+
Logs.warn (fun m -> m "%s" s);
75+
s
76+
in
77+
content := new_content;
78+
let old_resolver = !resolver in
79+
let nwaiter, nresolver = Lwt.wait () in
80+
waiter := nwaiter;
81+
resolver := nresolver;
82+
Dream.log "Asking browsers to reload";
83+
Lwt.wakeup_later old_resolver ();
84+
loop ()
85+
| _ -> loop ()
6586
in
6687
loop ()
6788
in

0 commit comments

Comments
 (0)