package merlin-lib
Merlin's libraries
Install
Dune Dependency
Authors
Maintainers
Sources
merlin-5.3-502.tbz
sha256=2cea46f12397fa6e31ef0c0d4f5e11c1cfd916ee49420694005c95ebb3aa24bc
sha512=e94abb9ae38149245337db033e2c3891c7ec772168e99abf1bda0216a894c0854e7170b56fe88eba83ec98f2ebc0f5c7c723e8db14f59eeb6dd348bec12c6d62
doc/src/merlin-lib.extend/extend_main.ml.html
Source file extend_main.ml
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 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
module P = Extend_protocol module R = P.Reader module Description = struct type t = P.description let make_v0 ~name ~version = { P.name; version } end module Reader = struct type t = (module R.V0) let make_v0 (x : (module R.V0)) : t = x module Make (V : R.V0) = struct open P.Reader let buffer = ref None let get_buffer () = match !buffer with | None -> invalid_arg "No buffer loaded" | Some buffer -> buffer let exec = function | Req_load buf -> buffer := Some (V.load buf); Res_loaded | Req_parse -> Res_parse (V.parse (get_buffer ())) | Req_parse_line (pos, str) -> Res_parse (V.parse_line (get_buffer ()) pos str) | Req_parse_for_completion pos -> let info, tree = V.for_completion (get_buffer ()) pos in Res_parse_for_completion (info, tree) | Req_get_ident_at pos -> Res_get_ident_at (V.ident_at (get_buffer ()) pos) | Req_print_outcome trees -> let print t = V.print_outcome Format.str_formatter t; Format.flush_str_formatter () in let trees = List.rev_map print trees in Res_print_outcome (List.rev trees) | Req_pretty_print p -> V.pretty_print Format.str_formatter p; Res_pretty_print (Format.flush_str_formatter ()) end end module Utils = struct (* Postpone messages until ready *) let send, set_ready = let is_ready = ref false in let postponed = ref [] in let really_send msg = output_value stdout msg in let set_ready () = is_ready := true; let postponed' = List.rev !postponed in postponed := []; List.iter really_send postponed' in let send msg = if !is_ready then really_send msg else postponed := msg :: !postponed in (send, set_ready) let notify msg = send (P.Notify msg) let debug msg = send (P.Debug msg) end module Handshake = struct let magic_number : string = "MERLINEXTEND002" type versions = { ast_impl_magic_number : string; ast_intf_magic_number : string; cmi_magic_number : string; cmt_magic_number : string } let versions = Config. { ast_impl_magic_number; ast_intf_magic_number; cmi_magic_number; cmt_magic_number } let negotiate (capabilities : P.capabilities) = output_string stdout magic_number; output_value stdout versions; output_value stdout capabilities; flush stdout; Utils.set_ready (); match input_value stdin with | exception End_of_file -> exit 0 | P.Start_communication -> () | _ -> prerr_endline "Unexpected value after handshake."; exit 1 exception Error of string let () = Printexc.register_printer (function | Error msg -> Some (Printf.sprintf "Extend_main.Handshake.Error %S" msg) | _ -> None) let negotiate_driver ext_name i o = let magic' = really_input_string i (String.length magic_number) in (if magic' <> magic_number then let msg = Printf.sprintf "Extension %s has incompatible protocol version %S (expected %S)" ext_name magic' magic_number in raise (Error msg)); let versions' : versions = input_value i in let check_v prj name = if prj versions <> prj versions' then let msg = Printf.sprintf "Extension %s %s has incompatible version %S (expected %S)" ext_name name (prj versions') (prj versions) in raise (Error msg) in check_v (fun x -> x.ast_impl_magic_number) "implementation AST"; check_v (fun x -> x.ast_intf_magic_number) "interface AST"; check_v (fun x -> x.cmi_magic_number) "compiled interface (CMI)"; check_v (fun x -> x.cmt_magic_number) "typedtree (CMT)"; output_value o P.Start_communication; flush o; let capabilities : P.capabilities = input_value i in capabilities end (** The main entry point of an extension. *) let extension_main ?reader desc = (* Check if invoked from Merlin *) begin match Sys.getenv "__MERLIN_MASTER_PID" with | exception Not_found -> Printf.eprintf "This is %s merlin extension, version %s.\n\ This binary should be invoked from merlin and cannot be used directly.\n\ %!" desc.P.name desc.P.version; exit 1 | _ -> () end; (* Communication happens on stdin/stdout. *) Handshake.negotiate { P.reader = reader <> None }; let reader = match reader with | None -> fun _ -> failwith "No reader" | Some (module R : R.V0) -> let module M = Reader.Make (R) in M.exec in let respond f = match f () with | (r : P.response) -> Utils.send r | exception exn -> let name = Printexc.exn_slot_name exn in let desc = Printexc.to_string exn in Utils.send (P.Exception (name, desc)) in let rec loop () = flush stdout; match input_value stdin with | exception End_of_file -> exit 0 | P.Start_communication -> prerr_endline "Unexpected message."; exit 2 | P.Reader_request request -> respond (fun () -> P.Reader_response (reader request)); loop () in loop ()
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>