this repo has no description

Sync with x-ocaml monorepo

- Bytestring interop for Marshal (Js.bytestring/to_bytestring)
- Worker Ready message on startup, client waits for it
- Add optional filename to Protocol.action for Merlin queries
(Complete_prefix, Type_enclosing, All_errors carry string option)
- Thread filename through config, make_pipeline, dispatch
- Vendor stdlib .cmi files in src/worker/static/stdlib/
- Symlink example/stdlib to vendored copy
- Simplify dune files and remove gen-time stdlib copy
- Add stubs.js for worker
- Logging in worker for debugging

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

+88 -136
+1 -1
dune-project
··· 1 - (lang dune 3.20) 1 + (lang dune 3.0) 2 2 3 3 (name merlin-js)
+1 -1
example/app.ml
··· 2 2 3 3 module Merlin = 4 4 Merlin_codemirror.Make (struct 5 - let worker_url = "worker/merlin_worker.bc.wasm.js" 5 + let worker_url = "merlin_worker.bc.js" 6 6 let cmis = { Protocol.static_cmis = Static_files.stdlib_cmis; dynamic_cmis = None } 7 7 end) 8 8
+7 -2
example/dune
··· 1 1 (executable 2 2 (name app) 3 3 (modes js) 4 - (promote (until-clean)) 4 + (promote) 5 5 (modules App) 6 6 (libraries 7 7 merlin_client ··· 12 12 (executable 13 13 (name dynamic) 14 14 (modes js) 15 - (promote (until-clean)) 15 + (promote) 16 16 (modules Dynamic) 17 17 (libraries 18 18 merlin_client 19 19 code-mirror 20 20 merlin-js.code-mirror)) 21 21 22 + (copy_files 23 + (mode promote) 24 + (files worker/merlin_worker.bc.js)) 25 + 22 26 (alias 23 27 (name all-js) 24 28 (deps 29 + merlin_worker.bc.js 25 30 app.bc.js 26 31 dynamic.bc.js))
+1
example/stdlib
··· 1 + ../src/worker/static/stdlib
-3
example/stdlib/.gitignore
··· 1 - * 2 - !.gitignore 3 - !dune
-14
example/stdlib/dune
··· 1 - (copy_files 2 - (alias all-js) 3 - (mode (promote (until-clean))) 4 - (files %{ocaml-config:standard_library}/*.cmi)) 5 - 6 - (copy_files 7 - (alias all-js) 8 - (mode (promote (until-clean))) 9 - (files %{ocaml-config:standard_library}/unix/*.cmi)) 10 - 11 - (copy_files 12 - (alias all-js) 13 - (mode (promote (until-clean))) 14 - (files %{ocaml-config:standard_library}/str/*.cmi))
+2 -12
example/worker/dune
··· 2 2 (name merlin_worker) 3 3 (modules merlin_worker) 4 4 (promote (until-clean)) 5 - (modes js wasm) 6 - (preprocess (pps js_of_ocaml-ppx)) 7 - (libraries worker js_of_ocaml)) 8 - 9 - 10 - (alias 11 - (name all-js) 12 - (deps 13 - merlin_worker.bc.js 14 - merlin_worker.bc.wasm.js 15 - app.bc.js 16 - dynamic.bc.js)) 5 + (modes js) 6 + (libraries worker))
+1 -1
src/client/dune
··· 1 1 (library 2 2 (name merlin_client) 3 3 (public_name merlin-js.client) 4 - (libraries js_of_ocaml protocol brr)) 4 + (libraries protocol brr))
+11 -15
src/client/merlin_client.ml
··· 33 33 Worker.post worker.worker action; 34 34 fut 35 35 36 - let query_errors worker (source : string) = 36 + let query_errors ?filename worker (source : string) = 37 37 let open Fut.Syntax in 38 - let action = Protocol.All_errors source in 38 + let action = Protocol.All_errors (source, filename) in 39 39 let+ data : Protocol.answer = query ~action worker in 40 40 match data with 41 41 | Protocol.Errors errors -> errors 42 42 | _ -> assert false 43 43 44 - let query_completions worker (source : string) position = 44 + let query_completions ?filename worker (source : string) position = 45 45 let open Fut.Syntax in 46 - let action = Protocol.Complete_prefix (source, position) in 46 + let action = Protocol.Complete_prefix (source, position, filename) in 47 47 let+ data : Protocol.answer = query ~action worker in 48 48 match data with 49 49 | Protocol.Completions compl -> compl 50 50 | _ -> assert false 51 51 52 - let query_type worker (source : string) position = 52 + let query_type ?filename worker (source : string) position = 53 53 let open Fut.Syntax in 54 - let action = Protocol.Type_enclosing (source, position) in 54 + let action = Protocol.Type_enclosing (source, position, filename) in 55 55 let+ data : Protocol.answer = query ~action worker in 56 56 match data with 57 57 | Protocol.Typed_enclosings l -> l ··· 70 70 include Brr_webworkers.Worker 71 71 72 72 let post t action = 73 - let bytes = Marshal.to_string action [] 74 - |> Js_of_ocaml.Js.bytestring in 73 + let bytes = Marshal.to_bytes action [] in 75 74 post t bytes 76 75 end 77 76 ··· 79 78 80 79 let make_worker url = 81 80 let worker = make_worker @@ Webworker.create @@ Jstr.of_string url in 82 - let ready, set_ready = Fut.create () in 83 81 let on_message m = 84 82 let m = Brr.Ev.as_type m in 85 - let data_marshaled = Brr_io.Message.Ev.data m |> Js_of_ocaml.Js.to_bytestring in 86 - let data : Protocol.answer = Marshal.from_string data_marshaled 0 in 87 - match data with 88 - | Protocol.Ready -> set_ready () 89 - | _ -> on_message worker data 83 + let data_marshaled : bytes = Brr_io.Message.Ev.data m in 84 + let data : Protocol.answer = Marshal.from_bytes data_marshaled 0 in 85 + on_message worker data 90 86 in 91 87 let _listen = 92 88 Brr.Ev.listen Brr_io.Message.Ev.message on_message 93 89 @@ Webworker.as_target worker.worker 94 90 in 95 - worker, ready 91 + worker
+2 -10
src/extension/merlin_codemirror.ml
··· 14 14 let linter worker = fun view -> 15 15 let open Fut.Syntax in 16 16 let doc = Utils.get_full_doc @@ Editor.View.state view in 17 - let* worker = worker in 18 17 let+ result = Merlin_client.query_errors worker doc in 19 18 List.map (fun Protocol.{ kind; loc; main; sub = _; source } -> 20 19 let from = loc.loc_start.pos_cnum in ··· 48 47 let source = Utils.get_full_doc @@ Autocomplete.Context.state ctx in 49 48 let pos = Autocomplete.Context.pos ctx in 50 49 let+ { from; to_; entries } = 51 - let* worker = worker in 52 50 Merlin_client.query_completions worker source (`Offset pos) 53 51 in 54 52 let options = ··· 74 72 let open Fut.Syntax in 75 73 let doc = Utils.get_full_doc @@ Editor.View.state view in 76 74 let pos = `Offset pos in 77 - let* worker = worker in 78 75 let+ result = Merlin_client.query_type worker doc pos in 79 76 match result with 80 77 | (loc, `String type_, _)::_ -> ··· 103 100 104 101 module Make (Config : Config) = struct 105 102 let worker = 106 - let open Fut.Syntax in 107 - let worker, ready = Merlin_client.make_worker Config.worker_url in 108 - let* () = ready in 109 - (* Initial Cmi loading should be the first request. Todo: make it clearer in 110 - the protocol that this is a mandatory initial exchange: Start worker -> 111 - worker sends Ready -> client sends Add_cmis *) 112 - let+ () = Merlin_client.add_cmis worker Config.cmis in 103 + let worker = Merlin_client.make_worker Config.worker_url in 104 + let _ = Merlin_client.add_cmis worker Config.cmis in 113 105 worker 114 106 115 107 open Extensions (Merlin_client.Webworker)
+5 -5
src/extension/merlin_codemirror.mli
··· 17 17 downloaded on demand. *) 18 18 end 19 19 20 - module Make : functor (_ : Config) -> sig 20 + module Make : functor (Config : Config) -> sig 21 21 22 22 val autocomplete : Code_mirror.Extension.t 23 23 (** An extension providing completions when typing *) ··· 37 37 38 38 type worker = Merlin_client.Make(Worker).worker 39 39 40 - val autocomplete : worker Fut.t -> Code_mirror.Extension.t 40 + val autocomplete : worker -> Code_mirror.Extension.t 41 41 (** An extension providing completions when typing *) 42 42 43 - val tooltip_on_hover : worker Fut.t -> Code_mirror.Extension.t 43 + val tooltip_on_hover : worker -> Code_mirror.Extension.t 44 44 (** An extension providing type-information when hovering code *) 45 45 46 - val linter : worker Fut.t -> Code_mirror.Extension.t 46 + val linter : worker -> Code_mirror.Extension.t 47 47 (** An extension that highlights errors and warnings in the code *) 48 48 49 - val all_extensions : worker Fut.t -> Code_mirror.Extension.t array 49 + val all_extensions : worker -> Code_mirror.Extension.t array 50 50 (** All the Merlin-specific extensions (does not include [ocaml]) *) 51 51 52 52 end
+3 -17
src/protocol/protocol.ml
··· 41 41 } 42 42 43 43 type action = 44 - | Complete_prefix of source * Msource.position 45 - | Type_enclosing of source * Msource.position 46 - | All_errors of source 44 + | Complete_prefix of source * Msource.position * string option 45 + | Type_enclosing of source * Msource.position * string option 46 + | All_errors of source * string option 47 47 | Add_cmis of cmis 48 48 49 - let action_to_string = function 50 - | Complete_prefix _ -> "Complete_prefix" 51 - | Type_enclosing _ -> "Type_enclosing" 52 - | All_errors _ -> "All_errors" 53 - | Add_cmis _ -> "Add_cmis" 54 - 55 49 type error = { 56 50 kind : Location.report_kind; 57 51 loc: Location.t; ··· 71 65 72 66 (* type errors = { from: int; to_: int; entries: error list } *) 73 67 type answer = 74 - | Ready 75 68 | Errors of error list 76 69 | Completions of completions 77 70 | Typed_enclosings of 78 71 (Location.t * [ `Index of int | `String of string ] * is_tail_position) list 79 72 | Added_cmis 80 - 81 - let answer_to_string = function 82 - | Ready -> "Ready" 83 - | Errors _ -> "Errors" 84 - | Completions _ -> "Completions" 85 - | Typed_enclosings _ -> "Type_enclosings" 86 - | Added_cmis -> "Added_cmis" 87 73 88 74 let report_source_to_string = function 89 75 | Location.Lexer -> "lexer"
+2
src/worker/dune
··· 1 1 (library 2 2 (name worker) 3 3 (public_name merlin-js.worker) 4 + (js_of_ocaml 5 + (javascript_files stubs.js)) 4 6 (preprocess (pps js_of_ocaml-ppx)) 5 7 (libraries 6 8 protocol
+2 -6
src/worker/static/dune
··· 11 11 12 12 (rule 13 13 (target static_files.ml) 14 - (deps 15 - (glob_files %{ocaml-config:standard_library}/*.cmi) 16 - (glob_files %{ocaml-config:standard_library}/unix/*.cmi) 17 - (glob_files %{ocaml-config:standard_library}/str/*.cmi)) 18 - (action (run ocaml %{dep:gen_static.ml} %{deps}))) 19 - 14 + (deps (glob_files stdlib/*.cmi)) 15 + (action (run ocaml %{dep:gen_static.ml})))
+17 -10
src/worker/static/gen_static.ml
··· 1 1 #use "topfind" ;; 2 2 #require "unix";; 3 3 4 + 5 + let rec iter_cmi ~f dir_handle = 6 + match Unix.readdir dir_handle with 7 + | exception End_of_file -> () 8 + | file -> 9 + if Filename.extension file = ".cmi" then 10 + f file; 11 + iter_cmi ~f dir_handle 12 + 4 13 let () = 14 + let cwd = Unix.getcwd () in 15 + let stdlib = Filename.concat cwd "stdlib" in 5 16 let out = open_out "static_files.ml" in 6 17 7 18 Printf.fprintf out "open Protocol\nlet stdlib_cmis = ["; 8 - for i = 1 to Array.length Sys.argv - 1 do 9 - let fullpath = Sys.argv.(i) in 10 - let module_name = 11 - Filename.basename fullpath 12 - |> String.capitalize_ascii 13 - |> Filename.remove_extension 14 - in 15 - Printf.fprintf out "{sc_name=%S; sc_content=[%%blob %S]};" module_name fullpath 16 - done; 17 - Printf.fprintf out "]\n"; 19 + let dir = Unix.opendir stdlib in 20 + iter_cmi ~f:(fun file -> 21 + let fullpath = Filename.concat stdlib file in 22 + let module_name = Filename.basename file |> String.capitalize_ascii |> Filename.remove_extension in 23 + Printf.fprintf out "{sc_name=%S; sc_content=[%%blob %S]};" module_name fullpath) dir; 24 + Printf.fprintf out "]\n"; 18 25 19 26 close_out out
src/worker/static/stdlib/arith_status.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/big_int.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/bigarray.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/camlinternalAtomic.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/camlinternalFormat.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/camlinternalFormatBasics.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/camlinternalLazy.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/camlinternalMod.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/camlinternalOO.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/dynlink.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/event.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/profiling.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/ratio.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/runtime_events.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/std_exit.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Arg.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Array.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__ArrayLabels.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Atomic.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Bigarray.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Bool.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Buffer.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Bytes.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__BytesLabels.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Callback.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Char.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Complex.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Condition.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Digest.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Domain.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Dynarray.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Effect.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Either.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Ephemeron.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Filename.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Float.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Format.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Fun.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Gc.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Genlex.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Hashtbl.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__In_channel.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Int.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Int32.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Int64.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Lazy.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Lexing.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__List.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__ListLabels.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Map.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Marshal.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__MoreLabels.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Mutex.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Nativeint.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Obj.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Oo.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Option.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Out_channel.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Parsing.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Pervasives.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Printexc.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Printf.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Queue.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Random.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Result.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Scanf.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Semaphore.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Seq.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Set.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Stack.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__StdLabels.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Stream.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__String.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__StringLabels.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Sys.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Type.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Uchar.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Unit.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/stdlib__Weak.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/str.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/thread.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/topdirs.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/unix.cmi

This is a binary file and will not be displayed.

src/worker/static/stdlib/unixLabels.cmi

This is a binary file and will not be displayed.

+4
src/worker/stubs.js
··· 1 + //Provides: caml_unix_times 2 + function caml_unix_times() { 3 + return 4.2 4 + }
+29 -39
src/worker/worker.ml
··· 1 1 open Merlin_utils 2 2 open Std 3 - open Js_of_ocaml 4 3 open Merlin_kernel 5 4 module Location = Ocaml_parsing.Location 6 5 7 6 let stdlib_path = "/static/cmis" 8 - let log s = Console.console##log (Js.string s) 9 7 10 8 let sync_get url = 9 + let open Js_of_ocaml in 11 10 let x = XmlHttpRequest.create () in 12 11 x##.responseType := Js.string "arraybuffer"; 13 12 x##_open (Js.string "GET") (Js.string url) Js._false; ··· 17 16 Js.Opt.case 18 17 (File.CoerceTo.arrayBuffer x##.response) 19 18 (fun () -> 20 - Console.console##log (Js.string "Failed to receive file"); 19 + Js_of_ocaml.Console.console##log (Js.string "Failed to receive file"); 21 20 None) 22 21 (fun b -> Some (Typed_array.String.of_arrayBuffer b)) 23 22 | _ -> None ··· 47 46 match fetch (filename_of_module name) with 48 47 | Some content -> 49 48 let name = Filename.(concat stdlib_path filename) in 50 - Sys_js.create_file ~name ~content 49 + Js_of_ocaml.Sys_js.create_file ~name ~content 51 50 | None -> ()) dcs.dcs_toplevel_modules; 52 51 53 52 let new_load ~allow_hidden ~unit_name = ··· 63 62 then begin 64 63 match fetch filename with 65 64 | Some x -> 66 - Sys_js.create_file ~name:fs_name ~content:x; 65 + Js_of_ocaml.Sys_js.create_file ~name:fs_name ~content:x; 67 66 (* At this point we need to tell merlin that the dir contents 68 67 have changed *) 69 68 reset_dirs () ··· 79 78 List.iter static_cmis ~f:(fun { Protocol.sc_name; sc_content } -> 80 79 let filename = Printf.sprintf "%s.cmi" (String.uncapitalize_ascii sc_name) in 81 80 let name = Filename.(concat stdlib_path filename) in 82 - Sys_js.create_file ~name ~content:sc_content); 81 + Js_of_ocaml.Sys_js.create_file ~name ~content:sc_content); 83 82 Option.iter ~f:add_dynamic_cmis dynamic_cmis; 84 83 Protocol.Added_cmis 85 84 86 - let config = 85 + let config ?filename () = 87 86 let initial = Mconfig.initial in 87 + let query = match filename with 88 + | Some f -> { initial.query with filename = f } 89 + | None -> initial.query 90 + in 88 91 { initial with 89 - merlin = { initial.merlin with 90 - stdlib = Some stdlib_path }} 92 + merlin = { initial.merlin with stdlib = Some stdlib_path }; 93 + query } 91 94 92 - let make_pipeline source = 93 - Mpipeline.make config source 95 + let make_pipeline ?filename source = 96 + Mpipeline.make (config ?filename ()) source 94 97 95 - let dispatch source query = 96 - let pipeline = make_pipeline source in 98 + let dispatch ?filename source query = 99 + let pipeline = make_pipeline ?filename source in 97 100 Mpipeline.with_pipeline pipeline @@ fun () -> ( 98 101 Query_commands.dispatch pipeline query 99 102 ) ··· 183 186 reconstructed_prefix 184 187 185 188 186 - let at_pos source position = 189 + let at_pos ?filename source position = 187 190 let prefix = prefix_of_position source position in 188 191 let `Offset to_ = Msource.get_offset source position in 189 192 let from = ··· 194 197 else 195 198 let query = Query_protocol.Complete_prefix (prefix, position, [], true, true) 196 199 in 197 - Some (from, to_, dispatch source query) 200 + Some (from, to_, dispatch ?filename source query) 198 201 end 199 202 (* 200 203 let dump () = ··· 208 211 |> Json.pretty_to_string *) 209 212 210 213 let on_message = function 211 - | Protocol.Complete_prefix (source, position) -> 214 + | Protocol.Complete_prefix (source, position, filename) -> 212 215 let source = Msource.make source in 213 - begin match Completion.at_pos source position with 216 + begin match Completion.at_pos ?filename source position with 214 217 | Some (from, to_, compl) -> 215 218 let entries = compl.entries in 216 219 Protocol.Completions { from; to_; entries; } 217 220 | None -> 218 221 Protocol.Completions { from = 0; to_ = 0; entries = []; } 219 222 end 220 - | Type_enclosing (source, position) -> 223 + | Type_enclosing (source, position, filename) -> 221 224 let source = Msource.make source in 222 225 let query = Query_protocol.Type_enclosing (None, position, None) in 223 - Protocol.Typed_enclosings (dispatch source query) 224 - | Protocol.All_errors source -> 226 + Protocol.Typed_enclosings (dispatch ?filename source query) 227 + | Protocol.All_errors (source, filename) -> 225 228 let source = Msource.make source in 226 229 let query = Query_protocol.Errors { 227 230 lexing = true; ··· 230 233 } 231 234 in 232 235 let errors = 233 - dispatch source query 236 + dispatch ?filename source query 234 237 |> List.map ~f:(fun (Location.{kind; sub; source; _} as error) -> 235 238 let of_sub sub = 236 239 Location.print_sub_msg Format.str_formatter sub; ··· 252 255 | Add_cmis cmis -> 253 256 add_cmis cmis 254 257 255 - let post res = 256 - Marshal.to_string res [] 257 - |> Js.bytestring 258 - |> Worker.post_message 259 - 260 258 let run () = 261 - Console.console##log (Js.string "Worker running"); 262 - Worker.set_onmessage (fun marshaled_message -> 263 - let action : Protocol.action = 264 - let str = Js.to_bytestring marshaled_message in 265 - Marshal.from_string str 0 266 - in 267 - log @@ Printf.sprintf "Received message with action %S" 268 - (Protocol.action_to_string action); 269 - let res = on_message action in 270 - log @@ Printf.sprintf "Sending message with answer %S" 271 - (Protocol.answer_to_string res); 272 - post res); 273 - post Protocol.Ready 259 + Js_of_ocaml.Worker.set_onmessage @@ fun marshaled_message -> 260 + let action : Protocol.action = Marshal.from_bytes marshaled_message 0 in 261 + let res = on_message action in 262 + let res = Marshal.to_bytes res [] in 263 + Js_of_ocaml.Worker.post_message res