package vcaml
OCaml bindings for the Neovim API
Install
Dune Dependency
Authors
Maintainers
Sources
vcaml-v0.16.0.tar.gz
sha256=dd123302c46af7ca6eda8a7806c78236fd217a8c73a2e1cd7da85f1d69ed1ae4
doc/src/vcaml.plugin/vcaml_plugin.ml.html
Source file vcaml_plugin.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
open Core open Async open Vcaml open Vcaml_plugin_intf module Oneshot = struct include Oneshot module Make (O : Arg) = struct let command ~summary = Async.Command.async_or_error ~summary (Core.Command.Param.return (fun () -> let open Deferred.Or_error.Let_syntax in let client = Client.create ~on_error:O.on_error in let shutdown = Ivar.create () in let invoked_rpc = Set_once.create () in let oneshot ~name f = match Set_once.get invoked_rpc with | Some previously_invoked -> Deferred.Or_error.error_s [%message "Already invoked an RPC" ~invoking:(name : string) (previously_invoked : string)] | None -> Set_once.set_exn invoked_rpc [%here] name; let%map result = f () in Ivar.fill shutdown (); result in List.iter O.rpc_handlers ~f:(fun (Sync_rpc { name; type_; f }) -> Private.register_request_blocking client ~name ~type_ ~f ~wrap_f:(oneshot ~name)); let%bind (_ : [ `connected ] Client.t) = Client.attach client Stdio ~time_source:(Time_source.wall_clock ()) in Ivar.read shutdown |> Deferred.ok)) ~behave_nicely_in_pipeline:false ;; end end module Persistent = struct include Persistent module Make (P : Arg) = struct let register_handlers ~client ~state ~shutdown = let shutdown = Ivar.fill_if_empty shutdown in List.iter P.rpc_handlers ~f:(function | Sync_rpc { name; type_; f } -> register_request_blocking client ~name ~type_ ~f:(f state ~shutdown) | Async_rpc { name; type_; f } -> Private.register_request_async client ~name ~type_ ~f:(f state ~shutdown) ~wrap_f:(fun f -> f () |> Deferred.Or_error.tag ~tag:P.name)) ;; let display_error_in_neovim ~client error = error |> Error.tag ~tag:P.name |> Error.to_string_hum |> Nvim.err_writeln |> run_join [%here] client (* We can't really do anything interesting with a failure to display an error. *) |> (Deferred.ignore_m : unit Deferred.Or_error.t -> unit Deferred.t) ;; let start ~client ~state ~shutdown = let%bind result = let open Deferred.Or_error.Let_syntax in let shutdown = Ivar.fill_if_empty shutdown in let channel = Client.channel client in let%bind () = P.on_startup client state ~shutdown in match P.vimscript_notify_fn with | None -> return () | Some function_name -> (match%bind wrap_viml_function ~type_:Defun.Vim.(Integer @-> return Object) ~function_name channel |> run_join [%here] client with | Integer 0 -> return () | value -> Deferred.Or_error.error_s [%message (sprintf "%s returned a value" function_name) ~_:(value : Msgpack.t)]) in let%bind () = match result with | Ok _ -> return () | Error error -> display_error_in_neovim ~client error in return result ;; let on_shutdown client state = let%bind result = P.on_shutdown client state in let%bind () = match result with | Ok _ -> return () | Error error -> display_error_in_neovim ~client error in return result ;; let command = Async.Command.async_or_error ~summary:P.description (Core.Command.Param.return (fun () -> let open Deferred.Or_error.Let_syntax in let state = P.init_state () in let shutdown = Ivar.create () in let client = Client.create ~on_error:P.on_error in register_handlers ~client ~state ~shutdown; let%bind client = Client.attach client (Unix `Child) ~time_source:(Time_source.wall_clock ()) in let%bind () = start ~client ~state ~shutdown in let%bind () = Ivar.read shutdown |> Deferred.ok in on_shutdown client state)) ~behave_nicely_in_pipeline:false ;; module For_testing = struct type plugin_state = P.state [@@deriving sexp_of] module State = struct type t = { plugin_state : plugin_state ; shutdown : unit -> unit ; wait_for_shutdown : unit Or_error.t Deferred.t } end let start ~client = let open Deferred.Or_error.Let_syntax in let state = P.init_state () in let shutdown_started = Ivar.create () in let shutdown_finished = Ivar.create () in don't_wait_for (let%bind.Deferred () = Ivar.read shutdown_started in let%map.Deferred result = on_shutdown client state in Ivar.fill shutdown_finished result); register_handlers ~client ~state ~shutdown:shutdown_started; let%bind () = start ~client ~state ~shutdown:shutdown_started in return { State.plugin_state = state ; shutdown = Ivar.fill shutdown_started ; wait_for_shutdown = Ivar.read shutdown_finished } ;; end end end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>