this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Refactor and improve API

+63 -259
+34 -34
src/extension/merlin_codemirror.ml
··· 8 8 let doc = Utils.get_full_doc @@ Editor.View.state view in 9 9 let+ result = Merlin_client.query_errors worker doc in 10 10 List.map (fun Protocol.{ kind; loc; main; sub = _; source } -> 11 - let from = loc.loc_start.pos_cnum in 12 - let to_ = loc.loc_end.pos_cnum in 13 - let source = Protocol.report_source_to_string source in 14 - let severity = match kind with 15 - | Report_error 16 - | Report_warning_as_error _ 17 - | Report_alert_as_error _ -> Lint.Diagnostic.Error 18 - | Report_warning _ -> Lint.Diagnostic.Warning 19 - | Report_alert _ -> Lint.Diagnostic.Info 20 - in 21 - Lint.Diagnostic.create ~source ~from ~to_ ~severity ~message:main () 22 - ) result 11 + let from = loc.loc_start.pos_cnum in 12 + let to_ = loc.loc_end.pos_cnum in 13 + let source = Protocol.report_source_to_string source in 14 + let severity = match kind with 15 + | Report_error 16 + | Report_warning_as_error _ 17 + | Report_alert_as_error _ -> Lint.Diagnostic.Error 18 + | Report_warning _ -> Lint.Diagnostic.Warning 19 + | Report_alert _ -> Lint.Diagnostic.Info 20 + in 21 + Lint.Diagnostic.create ~source ~from ~to_ ~severity ~message:main () 22 + ) result 23 23 |> Array.of_list 24 24 25 - let keywords = List.map 26 - (fun label -> Autocomplete.Completion.create ~label ~type_:"keyword" ()) 27 - [ 28 - "as"; "do"; "else"; "end"; "exception"; "fun"; "functor"; "if"; "in"; 29 - "include"; "let"; "of"; "open"; "rec"; "struct"; "then"; "type"; "val"; 30 - "while"; "with"; "and"; "assert"; "begin"; "class"; "constraint"; 31 - "done"; "downto"; "external"; "function"; "initializer"; "lazy"; 32 - "match"; "method"; "module"; "mutable"; "new"; "nonrec"; "object"; 33 - "private"; "sig"; "to"; "try"; "value"; "virtual"; "when"; 34 - ] 25 + let keywords = List.map 26 + (fun label -> Autocomplete.Completion.create ~label ~type_:"keyword" ()) 27 + [ 28 + "as"; "do"; "else"; "end"; "exception"; "fun"; "functor"; "if"; "in"; 29 + "include"; "let"; "of"; "open"; "rec"; "struct"; "then"; "type"; "val"; 30 + "while"; "with"; "and"; "assert"; "begin"; "class"; "constraint"; 31 + "done"; "downto"; "external"; "function"; "initializer"; "lazy"; 32 + "match"; "method"; "module"; "mutable"; "new"; "nonrec"; "object"; 33 + "private"; "sig"; "to"; "try"; "value"; "virtual"; "when"; 34 + ] 35 35 36 36 let merlin_completion worker = fun ctx -> 37 37 let open Fut.Syntax in ··· 40 40 let+ { from; to_; entries } = 41 41 Merlin_client.query_completions worker source (`Offset pos) 42 42 in 43 - let options = List.map (fun Query_protocol.Compl.{ name; desc; _ } -> 44 - Autocomplete.Completion.create ~label:name ~detail:desc () 45 - ) entries in 43 + let options = 44 + List.map (fun Query_protocol.Compl.{ name; desc; _ } -> 45 + Autocomplete.Completion.create ~label:name ~detail:desc ()) entries 46 + in 46 47 Some (Autocomplete.Result.create ~from ~to_ ~options ()) 47 48 48 49 let autocomplete worker = 49 - let config = Autocomplete.(config () 50 - ~override:[Source.create @@ merlin_completion worker; Source.from_list keywords]) 51 - in 50 + let override = [ 51 + Autocomplete.Source.create @@ merlin_completion worker; 52 + Autocomplete.Source.from_list keywords] 53 + in 54 + let config = Autocomplete.config () ~override in 52 55 Autocomplete.create ~config () 53 56 54 57 let tooltip_on_hover worker = 55 58 let open Tooltip in 56 - hover_tooltip 57 - (fun ~view ~pos ~side:_ -> 59 + hover_tooltip @@ 60 + fun ~view ~pos ~side:_ -> 58 61 let open Fut.Syntax in 59 62 let doc = Utils.get_full_doc @@ Editor.View.state view in 60 63 let pos = `Offset pos in ··· 68 71 let pos = loc.loc_start.pos_cnum in 69 72 let end_ = loc.loc_end.pos_cnum in 70 73 Some (Tooltip.create ~pos ~end_ ~above:true ~arrow:true ~create ()) 71 - | _ -> None) 74 + | _ -> None 72 75 73 76 let ocaml = Jv.get Jv.global "__CM__mllike" |> Stream.Language.of_jv 74 77 let ocaml = Stream.Language.define ocaml 75 78 76 79 module Make (Config : sig val worker_url : string end) = struct 77 80 let worker = Merlin_client.make_worker Config.worker_url 78 - 79 81 let autocomplete = autocomplete worker 80 82 let tooltip_on_hover = tooltip_on_hover worker 81 - 82 83 let linter = Lint.create (linter worker) 83 84 84 85 let all_extensions = [| 85 - ocaml; 86 86 linter; 87 87 autocomplete; 88 88 tooltip_on_hover
+21
src/extension/merlin_codemirror.mli
··· 1 + module Utils : sig 2 + val get_el_by_id : string -> Brr.El.t 3 + val get_full_doc : Code_mirror.Editor.State.t -> string 4 + end 5 + 6 + val ocaml : Code_mirror.Extension.t 7 + (** An extension providing OCaml syntax highlighting *) 8 + 9 + module Make : functor (Config : sig val worker_url : string end) -> sig 10 + val autocomplete : Code_mirror.Extension.t 11 + (** An extension providing completions when typing *) 12 + 13 + val tooltip_on_hover : Code_mirror.Extension.t 14 + (** An extension providing type-information when hovering code *) 15 + 16 + val linter : Code_mirror.Extension.t 17 + (** An extension that highlights errors and warnings in the code *) 18 + 19 + val all_extensions : Code_mirror.Extension.t array 20 + (** All the Merlin-specific extensions (does not include [ocaml]) *) 21 + end
-14
src/worker/bin/dune
··· 1 - (env 2 - (_ (js_of_ocaml (compilation_mode whole_program)))) 3 - 4 - (executable 5 - (name merlin_worker) 6 - (modules merlin_worker) 7 - (promote (until-clean)) 8 - (modes js) 9 - (libraries worker)) 10 - 11 - ; (install 12 - ; (files merlin_worker.bc.js) 13 - ; (section share) 14 - ; (package merlin-js))
src/worker/bin/merlin_worker.ml

This is a binary file and will not be displayed.

src/worker/lib/dune src/worker/dune
src/worker/lib/static/dune src/worker/static/dune
src/worker/lib/static/gen_static.ml src/worker/static/gen_static.ml
src/worker/lib/static/stdlib/bigarray.cmi src/worker/static/stdlib/bigarray.cmi
src/worker/lib/static/stdlib/camlinternalAtomic.cmi src/worker/static/stdlib/camlinternalAtomic.cmi
src/worker/lib/static/stdlib/camlinternalFormat.cmi src/worker/static/stdlib/camlinternalFormat.cmi
src/worker/lib/static/stdlib/camlinternalFormatBasics.cmi src/worker/static/stdlib/camlinternalFormatBasics.cmi
src/worker/lib/static/stdlib/camlinternalLazy.cmi src/worker/static/stdlib/camlinternalLazy.cmi
src/worker/lib/static/stdlib/camlinternalMod.cmi src/worker/static/stdlib/camlinternalMod.cmi
src/worker/lib/static/stdlib/camlinternalOO.cmi src/worker/static/stdlib/camlinternalOO.cmi
src/worker/lib/static/stdlib/dynlink.cmi src/worker/static/stdlib/dynlink.cmi
src/worker/lib/static/stdlib/profiling.cmi src/worker/static/stdlib/profiling.cmi
src/worker/lib/static/stdlib/std_exit.cmi src/worker/static/stdlib/std_exit.cmi
src/worker/lib/static/stdlib/stdlib.cmi src/worker/static/stdlib/stdlib.cmi
src/worker/lib/static/stdlib/stdlib__Arg.cmi src/worker/static/stdlib/stdlib__Arg.cmi
src/worker/lib/static/stdlib/stdlib__Array.cmi src/worker/static/stdlib/stdlib__Array.cmi
src/worker/lib/static/stdlib/stdlib__ArrayLabels.cmi src/worker/static/stdlib/stdlib__ArrayLabels.cmi
src/worker/lib/static/stdlib/stdlib__Atomic.cmi src/worker/static/stdlib/stdlib__Atomic.cmi
src/worker/lib/static/stdlib/stdlib__Bigarray.cmi src/worker/static/stdlib/stdlib__Bigarray.cmi
src/worker/lib/static/stdlib/stdlib__Bool.cmi src/worker/static/stdlib/stdlib__Bool.cmi
src/worker/lib/static/stdlib/stdlib__Buffer.cmi src/worker/static/stdlib/stdlib__Buffer.cmi
src/worker/lib/static/stdlib/stdlib__Bytes.cmi src/worker/static/stdlib/stdlib__Bytes.cmi
src/worker/lib/static/stdlib/stdlib__BytesLabels.cmi src/worker/static/stdlib/stdlib__BytesLabels.cmi
src/worker/lib/static/stdlib/stdlib__Callback.cmi src/worker/static/stdlib/stdlib__Callback.cmi
src/worker/lib/static/stdlib/stdlib__Char.cmi src/worker/static/stdlib/stdlib__Char.cmi
src/worker/lib/static/stdlib/stdlib__Complex.cmi src/worker/static/stdlib/stdlib__Complex.cmi
src/worker/lib/static/stdlib/stdlib__Digest.cmi src/worker/static/stdlib/stdlib__Digest.cmi
src/worker/lib/static/stdlib/stdlib__Either.cmi src/worker/static/stdlib/stdlib__Either.cmi
src/worker/lib/static/stdlib/stdlib__Ephemeron.cmi src/worker/static/stdlib/stdlib__Ephemeron.cmi
src/worker/lib/static/stdlib/stdlib__Filename.cmi src/worker/static/stdlib/stdlib__Filename.cmi
src/worker/lib/static/stdlib/stdlib__Float.cmi src/worker/static/stdlib/stdlib__Float.cmi
src/worker/lib/static/stdlib/stdlib__Format.cmi src/worker/static/stdlib/stdlib__Format.cmi
src/worker/lib/static/stdlib/stdlib__Fun.cmi src/worker/static/stdlib/stdlib__Fun.cmi
src/worker/lib/static/stdlib/stdlib__Gc.cmi src/worker/static/stdlib/stdlib__Gc.cmi
src/worker/lib/static/stdlib/stdlib__Genlex.cmi src/worker/static/stdlib/stdlib__Genlex.cmi
src/worker/lib/static/stdlib/stdlib__Hashtbl.cmi src/worker/static/stdlib/stdlib__Hashtbl.cmi
src/worker/lib/static/stdlib/stdlib__In_channel.cmi src/worker/static/stdlib/stdlib__In_channel.cmi
src/worker/lib/static/stdlib/stdlib__Int.cmi src/worker/static/stdlib/stdlib__Int.cmi
src/worker/lib/static/stdlib/stdlib__Int32.cmi src/worker/static/stdlib/stdlib__Int32.cmi
src/worker/lib/static/stdlib/stdlib__Int64.cmi src/worker/static/stdlib/stdlib__Int64.cmi
src/worker/lib/static/stdlib/stdlib__Lazy.cmi src/worker/static/stdlib/stdlib__Lazy.cmi
src/worker/lib/static/stdlib/stdlib__Lexing.cmi src/worker/static/stdlib/stdlib__Lexing.cmi
src/worker/lib/static/stdlib/stdlib__List.cmi src/worker/static/stdlib/stdlib__List.cmi
src/worker/lib/static/stdlib/stdlib__ListLabels.cmi src/worker/static/stdlib/stdlib__ListLabels.cmi
src/worker/lib/static/stdlib/stdlib__Map.cmi src/worker/static/stdlib/stdlib__Map.cmi
src/worker/lib/static/stdlib/stdlib__Marshal.cmi src/worker/static/stdlib/stdlib__Marshal.cmi
src/worker/lib/static/stdlib/stdlib__MoreLabels.cmi src/worker/static/stdlib/stdlib__MoreLabels.cmi
src/worker/lib/static/stdlib/stdlib__Nativeint.cmi src/worker/static/stdlib/stdlib__Nativeint.cmi
src/worker/lib/static/stdlib/stdlib__Obj.cmi src/worker/static/stdlib/stdlib__Obj.cmi
src/worker/lib/static/stdlib/stdlib__Oo.cmi src/worker/static/stdlib/stdlib__Oo.cmi
src/worker/lib/static/stdlib/stdlib__Option.cmi src/worker/static/stdlib/stdlib__Option.cmi
src/worker/lib/static/stdlib/stdlib__Out_channel.cmi src/worker/static/stdlib/stdlib__Out_channel.cmi
src/worker/lib/static/stdlib/stdlib__Parsing.cmi src/worker/static/stdlib/stdlib__Parsing.cmi
src/worker/lib/static/stdlib/stdlib__Pervasives.cmi src/worker/static/stdlib/stdlib__Pervasives.cmi
src/worker/lib/static/stdlib/stdlib__Printexc.cmi src/worker/static/stdlib/stdlib__Printexc.cmi
src/worker/lib/static/stdlib/stdlib__Printf.cmi src/worker/static/stdlib/stdlib__Printf.cmi
src/worker/lib/static/stdlib/stdlib__Queue.cmi src/worker/static/stdlib/stdlib__Queue.cmi
src/worker/lib/static/stdlib/stdlib__Random.cmi src/worker/static/stdlib/stdlib__Random.cmi
src/worker/lib/static/stdlib/stdlib__Result.cmi src/worker/static/stdlib/stdlib__Result.cmi
src/worker/lib/static/stdlib/stdlib__Scanf.cmi src/worker/static/stdlib/stdlib__Scanf.cmi
src/worker/lib/static/stdlib/stdlib__Seq.cmi src/worker/static/stdlib/stdlib__Seq.cmi
src/worker/lib/static/stdlib/stdlib__Set.cmi src/worker/static/stdlib/stdlib__Set.cmi
src/worker/lib/static/stdlib/stdlib__Stack.cmi src/worker/static/stdlib/stdlib__Stack.cmi
src/worker/lib/static/stdlib/stdlib__StdLabels.cmi src/worker/static/stdlib/stdlib__StdLabels.cmi
src/worker/lib/static/stdlib/stdlib__Stream.cmi src/worker/static/stdlib/stdlib__Stream.cmi
src/worker/lib/static/stdlib/stdlib__String.cmi src/worker/static/stdlib/stdlib__String.cmi
src/worker/lib/static/stdlib/stdlib__StringLabels.cmi src/worker/static/stdlib/stdlib__StringLabels.cmi
src/worker/lib/static/stdlib/stdlib__Sys.cmi src/worker/static/stdlib/stdlib__Sys.cmi
src/worker/lib/static/stdlib/stdlib__Uchar.cmi src/worker/static/stdlib/stdlib__Uchar.cmi
src/worker/lib/static/stdlib/stdlib__Unit.cmi src/worker/static/stdlib/stdlib__Unit.cmi
src/worker/lib/static/stdlib/stdlib__Weak.cmi src/worker/static/stdlib/stdlib__Weak.cmi
src/worker/lib/static/stdlib/str.cmi src/worker/static/stdlib/str.cmi
src/worker/lib/static/stdlib/topdirs.cmi src/worker/static/stdlib/topdirs.cmi
src/worker/lib/static/stdlib/unix.cmi src/worker/static/stdlib/unix.cmi
src/worker/lib/static/stdlib/unixLabels.cmi src/worker/static/stdlib/unixLabels.cmi
src/worker/lib/stubs.js src/worker/stubs.js
-201
src/worker/lib/worker.ml
··· 1 - open Merlin_utils 2 - open Brr 3 - open Std 4 - open Merlin_kernel 5 - module Location = Ocaml_parsing.Location 6 - 7 - module Make () : sig end = struct 8 - 9 - (* Load the CMIs into the pseudo file-system *) 10 - (* This add roughly 3mo to the final script. These could be loaded dynamically 11 - after the worker *) 12 - let () = List.iter ~f:(fun (path, content) -> 13 - let name = Filename.(concat "/static/stdlib" (basename path)) in 14 - Js_of_ocaml.Sys_js.create_file ~name ~content 15 - ) Static_files.stdlib_cmis 16 - 17 - let config = 18 - let initial = Mconfig.initial in 19 - { initial with 20 - merlin = { initial.merlin with 21 - stdlib = Some "/static/stdlib" }} 22 - 23 - let make_pipeline source = 24 - Mpipeline.make config source 25 - 26 - let dispatch source query = 27 - let pipeline = make_pipeline source in 28 - Mpipeline.with_pipeline pipeline @@ fun () -> ( 29 - Query_commands.dispatch pipeline query 30 - ) 31 - 32 - 33 - module Completion = struct 34 - (* Prefixing code from ocaml-lsp-server *) 35 - let rfindi = 36 - let rec loop s ~f i = 37 - if i < 0 then 38 - None 39 - else if f (String.unsafe_get s i) then 40 - Some i 41 - else 42 - loop s ~f (i - 1) 43 - in 44 - fun ?from s ~f -> 45 - let from = 46 - let len = String.length s in 47 - match from with 48 - | None -> len - 1 49 - | Some i -> 50 - if i > len - 1 then 51 - raise @@ Invalid_argument "rfindi: invalid from" 52 - else 53 - i 54 - in 55 - loop s ~f from 56 - let lsplit2 s ~on = 57 - match String.index_opt s on with 58 - | None -> None 59 - | Some i -> 60 - let open String in 61 - Some (sub s ~pos:0 ~len:i, sub s ~pos:(i + 1) ~len:(length s - i - 1)) 62 - 63 - (** @see <https://ocaml.org/manual/lex.html> reference *) 64 - let prefix_of_position ?(short_path = false) source position = 65 - match Msource.text source with 66 - | "" -> "" 67 - | text -> 68 - let from = 69 - let (`Offset index) = Msource.get_offset source position in 70 - min (String.length text - 1) (index - 1) 71 - in 72 - let pos = 73 - let should_terminate = ref false in 74 - let has_seen_dot = ref false in 75 - let is_prefix_char c = 76 - if !should_terminate then 77 - false 78 - else 79 - match c with 80 - | 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '\'' | '_' 81 - (* Infix function characters *) 82 - | '$' | '&' | '*' | '+' | '-' | '/' | '=' | '>' 83 - | '@' | '^' | '!' | '?' | '%' | '<' | ':' | '~' | '#' -> 84 - true 85 - | '`' -> 86 - if !has_seen_dot then 87 - false 88 - else ( 89 - should_terminate := true; 90 - true 91 - ) | '.' -> 92 - has_seen_dot := true; 93 - not short_path 94 - | _ -> false 95 - in 96 - rfindi text ~from ~f:(fun c -> not (is_prefix_char c)) 97 - in 98 - let pos = 99 - match pos with 100 - | None -> 0 101 - | Some pos -> pos + 1 102 - in 103 - let len = from - pos + 1 in 104 - let reconstructed_prefix = String.sub text ~pos ~len in 105 - (* if we reconstructed [~f:ignore] or [?f:ignore], we should take only 106 - [ignore], so: *) 107 - if 108 - String.is_prefixed ~by:"~" reconstructed_prefix 109 - || String.is_prefixed ~by:"?" reconstructed_prefix 110 - then 111 - match lsplit2 reconstructed_prefix ~on:':' with 112 - | Some (_, s) -> s 113 - | None -> reconstructed_prefix 114 - else 115 - reconstructed_prefix 116 - 117 - 118 - let at_pos source position = 119 - let prefix = prefix_of_position source position in 120 - let `Offset to_ = Msource.get_offset source position in 121 - let from = 122 - to_ - String.length (prefix_of_position ~short_path:true source position) 123 - in 124 - 125 - Console.(log ["Prefix:";prefix]); 126 - if prefix = "" then 127 - None 128 - else 129 - let query = Query_protocol.Complete_prefix (prefix, position, [], true, true) 130 - in 131 - Some (from, to_, dispatch source query) 132 - end 133 - (* 134 - let dump () = 135 - let query = Query_protocol.Dump [`String "paths"] in 136 - dispatch (Msource.make "") query *) 137 - 138 - (* let dump_config () = 139 - let pipeline = make_pipeline (Msource.make "") in 140 - Mpipeline.with_pipeline pipeline @@ fun () -> 141 - Mconfig.dump (Mpipeline.final_config pipeline) 142 - |> Json.pretty_to_string *) 143 - 144 - let on_message e = 145 - let marshaled_message = Brr_io.Message.Ev.data e in 146 - let action : Protocol.action = 147 - Marshal.from_bytes marshaled_message 0 148 - in 149 - Console.(log ["w: Received message:"; action]); 150 - let res = 151 - match action with 152 - | Complete_prefix (source, position) -> 153 - let source = Msource.make source in 154 - begin match Completion.at_pos source position with 155 - | Some (from, to_, compl) -> 156 - let entries = compl.entries in 157 - Protocol.Completions { from; to_; entries; } 158 - | None -> 159 - Protocol.Completions { from = 0; to_ = 0; entries = []; } 160 - end 161 - | Type_enclosing (source, position) -> 162 - let source = Msource.make source in 163 - let query = Query_protocol.Type_enclosing (None, position, None) in 164 - Protocol.Typed_enclosings (dispatch source query) 165 - | Protocol.All_errors source -> 166 - Console.(log ["w: Query errors"]); 167 - let source = Msource.make source in 168 - let query = Query_protocol.Errors { 169 - lexing = true; 170 - parsing = true; 171 - typing = true; 172 - } 173 - in 174 - let errors = 175 - dispatch source query 176 - |> List.map ~f:(fun (Location.{kind; main=_ ; sub; source} as error) -> 177 - let of_sub sub = 178 - Location.print_sub_msg Format.str_formatter sub; 179 - String.trim (Format.flush_str_formatter ()) 180 - in 181 - let loc = Location.loc_of_report error in 182 - let main = 183 - Format.asprintf "@[%a@]" Location.print_main error |> String.trim 184 - in 185 - Protocol.{ 186 - kind; 187 - loc; 188 - main; 189 - sub = List.map ~f:of_sub sub; 190 - source; 191 - }) 192 - in 193 - Protocol.Errors errors 194 - in 195 - let res = Marshal.to_bytes res [] in 196 - Brr_webworkers.Worker.G.post res 197 - 198 - let () = Jv.(set global "onmessage" @@ Jv.repr on_message) 199 - 200 - (* let () = Console.(log [dump (); dump_config ()]) *) 201 - end
+8 -10
src/worker/merlin_worker.ml src/worker/worker.ml
··· 4 4 open Merlin_kernel 5 5 module Location = Ocaml_parsing.Location 6 6 7 - (* Load the CMIs into the pseudo file-system *) 8 - (* This add roughly 3mo to the final script. These could be loaded dynamically 9 - after the worker *) 10 - let () = List.iter ~f:(fun (path, content) -> 11 - let name = Filename.(concat "/static/stdlib" (basename path)) in 12 - Js_of_ocaml.Sys_js.create_file ~name ~content 13 - ) Static_files.stdlib_cmis 14 - 15 7 let config = 16 8 let initial = Mconfig.initial in 17 9 { initial with ··· 193 185 let res = Marshal.to_bytes res [] in 194 186 Brr_webworkers.Worker.G.post res 195 187 196 - let () = Jv.(set global "onmessage" @@ Jv.repr on_message) 197 188 198 - (* let () = Console.(log [dump (); dump_config ()]) *) 189 + let run () = 190 + (* Load the CMIs into the pseudo file-system *) 191 + (* This add roughly 3mo to the final script. These could be loaded dynamically 192 + after the worker *) 193 + List.iter Static_files.stdlib_cmis ~f:(fun (path, content) -> 194 + let name = Filename.(concat "/static/stdlib" (basename path)) in 195 + Js_of_ocaml.Sys_js.create_file ~name ~content); 196 + Jv.(set global "onmessage" @@ Jv.repr on_message)