package vcaml
OCaml bindings for the Neovim API
Install
Dune Dependency
Authors
Maintainers
Sources
vcaml-v0.15.0.tar.gz
sha256=0dbf2526a24d838988ae9a327550fdd9f0328dbdca9d026430fb4b579e0e0442
doc/src/vcaml/vcaml.ml.html
Source file vcaml.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 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
module Unshadow = struct module Buffer = Buffer module Command = Command end open Core open Async module Api_call = Api_call module Buffer = Unshadow.Buffer module Channel_info = Channel_info module Client_info = Client_info module Color = Color module Command = Unshadow.Command module Error_type = Nvim_internal.Error_type module Highlighted_text = Highlighted_text module Keymap = Keymap module Mark = Mark module Mode = Mode module Namespace = Namespace module Nvim = Nvim module Position = Position module Tabpage = Tabpage module Type = Nvim_internal.Phantom module Ui = Ui module Vcaml_error = Vcaml_error module Version = Nvim_internal.Version module Window = Window let version = Nvim_internal.version module Client = struct include Client module Connection_type = struct type 'state client = 'state t type _ t = | Unix : [ `Child | `Socket of string ] -> [ `connected ] client t | Stdio : [ `connected ] client t | Embed : { prog : string ; args : string list ; working_dir : string ; env : Core_unix.env } -> ([ `connected ] client * Async.Process.t) t [@@deriving sexp_of] end let create ~on_error = let on_error = match on_error with | `Call f -> f | `Raise -> Fn.compose Error.raise Vcaml_error.to_error in create ~on_error ;; let attach (type a) ?(close_reader_and_writer_on_disconnect = true) client (connection_type : a Connection_type.t) ~time_source : a Deferred.Or_error.t = let connect = connect client ~close_reader_and_writer_on_disconnect ~time_source in match connection_type with | Unix socket -> let socket = match socket with | `Socket socket -> socket | `Child -> Sys.getenv_exn "NVIM_LISTEN_ADDRESS" in let socket = Tcp.Where_to_connect.of_file socket in let%bind _addr, reader, writer = Tcp.connect socket in connect reader writer | Stdio -> connect (force Reader.stdin) (force Writer.stdout) | Embed { prog; args; working_dir; env } -> (match List.exists args ~f:(String.equal "--embed") with | false -> Deferred.Or_error.error_s [%message "Tried to create a VCaml client for an embedded Neovim process, but --embed \ flag was not passed" ~_:(connection_type : _ Connection_type.t)] | true -> let open Deferred.Or_error.Let_syntax in let%bind nvim = Process.create ~prog ~args ~working_dir ~env () in let%bind client = connect (Process.stdout nvim) (Process.stdin nvim) in return (client, nvim)) ;; let close client = let client = Type_equal.conv Private.eq client in let (Connected state) = client.state in state.close () ;; let rpc_channel_id client = let client = Type_equal.conv Private.eq client in let (Connected state) = client.state in Set_once.get_exn state.rpc_channel_id [%here] ;; end let run = Api_call.run let run_join = Api_call.run_join module Defun = struct module Vim = struct type ('f, 'leftmost_input, 'out) t = | Nullary : 'output Type.t -> ('output Api_call.Or_error.t, unit, 'output) t | Cons : 'a Type.t * ('b, _, 'output) t -> ('a -> 'b, 'a, 'output) t let return t = Nullary t let ( @-> ) a t = Cons (a, t) let rec make_fn : type fn i out. string -> (fn, i, out) t -> (Msgpack.t list -> Msgpack.t list) -> fn = fun function_name arity f -> (* Due to the fact that OCaml does not (easily) support higher-ranked polymorphism, we need to construct the function [to_msgpack] *after* we unpack this GADT, so it can have the type [i -> Msgpack.t] (which is fixed by [arity] in this function). Otherwise, it needs the type [forall 'a . 'a witness -> 'a -> Msgpack.t], which is not that easily expressible. *) match arity with | Nullary return_type -> let args = f [] in let open Api_call.Let_syntax in let%map result = Nvim_internal.nvim_call_function ~fn:function_name ~args |> Api_call.of_api_result in let open Or_error.Let_syntax in let%bind result = result in Extract.value return_type result |> Or_error.tag ~tag:"return type given to [wrap_viml_function] is incorrect" | Cons (t, rest) -> fun i -> let to_msgpack = Extract.inject t in make_fn function_name rest (fun args -> f (to_msgpack i :: args)) ;; end module Ocaml = struct module Sync = struct type ('f, 'leftmost_input) t = | Nullary : ('output Type.t * ('output_deferred_or_error, 'output Deferred.Or_error.t) Type_equal.t) -> ('output_deferred_or_error, unit) t | Varargs : ('leftmost Type.t * 'output Type.t * ('output_deferred_or_error, 'output Deferred.Or_error.t) Type_equal.t) -> ('leftmost list -> 'output_deferred_or_error, 'leftmost list) t | Cons : 'a Type.t * ('b, _) t -> ('a -> 'b, 'a) t let valid_number_of_args : ('fn, 'i) t -> int -> bool = let rec f : type fn i. (fn, i) t -> required:int -> int -> bool = fun t ~required -> match t with | Nullary _ -> ( = ) required | Varargs _ -> Int.( <= ) required | Cons (_, t) -> f t ~required:(required + 1) in f ~required:0 ;; let rec make_fn : type fn i. (fn, i) t -> fn -> Msgpack.t list -> Msgpack.t Deferred.Or_error.t = fun arity f l -> let open Deferred.Or_error.Let_syntax in match arity, l with | Nullary (return_type, T), [] -> let%map v = f in Extract.inject return_type v | Varargs (leftmost, output, T), l -> (match List.map l ~f:(Extract.value leftmost) |> Or_error.combine_errors with | Error error -> Deferred.Or_error.error_s [%message "Wrong argument type" ~expected_type:(leftmost : _ Type.t) (error : Error.t)] | Ok l -> let%map v = f l in Extract.inject output v) | Cons (leftmost, rest), x :: xs -> let%bind v = Extract.value leftmost x |> Deferred.return in make_fn rest (f v) xs | _, _ -> (* This should be caught by the [valid_number_of_args] check. *) Deferred.Or_error.error_s [%message "[BUG] Wrong number of arguments"] ;; let return t = Nullary (t, T) let ( @-> ) a b = Cons (a, b) module Expert = struct let varargs ~args_type ~return_type = Varargs (args_type, return_type, T) end end module Async = struct exception Failed_to_parse of Error.t type 'f t = | Unit : unit Deferred.Or_error.t t | Varargs : 'a Type.t -> ('a list -> unit Deferred.Or_error.t) t | Cons : 'a Type.t * 'b t -> ('a -> 'b) t let valid_number_of_args : 'fn t -> int -> bool = let rec f : type fn. fn t -> required:int -> int -> bool = fun t ~required -> match t with | Unit -> ( = ) required | Varargs _ -> Int.( <= ) required | Cons (_, t) -> f t ~required:(required + 1) in f ~required:0 ;; let rec make_fn : type fn. fn t -> fn -> Msgpack.t list -> unit Deferred.Or_error.t = fun arity f l -> match arity, l with | Varargs typ, l -> (match List.map l ~f:(Extract.value typ) |> Or_error.combine_errors with | Error error -> raise (Failed_to_parse (Error.tag error ~tag:"Wrong argument type")) | Ok l -> f l) | Unit, [] -> f | Cons (leftmost, rest), x :: xs -> (match%bind Extract.value leftmost x |> return with | Ok v -> let f' = f v in make_fn rest f' xs | Error error -> raise (Failed_to_parse (Error.tag error ~tag:"Wrong argument type"))) | _ -> (* This should be caught by the [valid_number_of_args] check. *) raise (Failed_to_parse (Error.of_string "[BUG] Wrong number of arguments")) ;; let unit = Unit let ( @-> ) a b = Cons (a, b) module Expert = struct let varargs typ = Varargs typ end end end end let wrap_viml_function ~type_ ~function_name = Defun.Vim.make_fn function_name type_ Fn.id let register_request_blocking_internal client ~name ~type_ ~f ~wrap_f = let client = Type_equal.conv Client.Private.eq client in let valid_number_of_args = Defun.Ocaml.Sync.valid_number_of_args type_ in let f ~keyboard_interrupted client params = match valid_number_of_args (List.length params) with | false -> Deferred.Or_error.error_string "Wrong number of arguments" | true -> wrap_f (fun () -> Defun.Ocaml.Sync.make_fn type_ (f ~keyboard_interrupted ~client) params) in client.register_request_blocking ~name ~f ;; let register_request_async_internal client ~name ~type_ ~f ~wrap_f = let client = Type_equal.conv Client.Private.eq client in let valid_number_of_args = Defun.Ocaml.Async.valid_number_of_args type_ in let f client params = let event = { Msgpack_rpc.Event.method_name = name; params } in match valid_number_of_args (List.length params) with | false -> Error.create_s [%message "Wrong number of arguments" (event : Msgpack_rpc.Event.t)] |> Notifier.error client | true -> don't_wait_for (match%map Monitor.try_with ~extract_exn:true (fun () -> wrap_f (fun () -> Defun.Ocaml.Async.make_fn type_ (f ~client) params)) with | Ok (Ok ()) -> () | Ok (Error error) -> Notifier.error client error | Error (Defun.Ocaml.Async.Failed_to_parse error) -> Notifier.error client (Error.tag_s error ~tag:[%sexp (event : Msgpack_rpc.Event.t)]) | Error exn -> raise exn) in client.register_request_async ~name ~f ;; let register_request_async = register_request_async_internal ~wrap_f:(fun f -> f ()) let register_request_blocking = register_request_blocking_internal ~wrap_f:(fun f -> f ()) module Expert = struct module Notifier = Notifier end module Private = struct let register_request_async = register_request_async_internal let register_request_blocking = register_request_blocking_internal end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>