package ecaml
Library for writing Emacs plugin in OCaml
Install
Dune Dependency
Authors
Maintainers
Sources
ecaml-v0.16.0.tar.gz
sha256=d9c6f98e7b0906a7e3d332d1a30fe950b59586b860e4f051348ea854c3ae3434
doc/src/ecaml.ecaml_value/ecaml_callback.ml.html
Source file ecaml_callback.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
open! Core open! Import module Scheduler = Async_unix.Async_unix_private.Raw_scheduler let scheduler = Scheduler.t () module Arity = struct type 'callback t = | Arity1 : ('a1 -> 'r) t | Arity2 : ('a1 -> 'a2 -> 'r) t [@@deriving sexp_of] end open Arity type 'callback t = { arity : 'callback Arity.t ; name : string } [@@deriving sexp_of] let report_exn_when_calling_callback = let out_of_memory_message = "Ecaml received Out_of_memory" in let out_of_memory_value = out_of_memory_message |> Value.of_utf8_bytes in function | Out_of_memory -> (try Value.Private.message_zero_alloc out_of_memory_value with | _ -> eprintf "%s" out_of_memory_message) | exn -> let sexp = [%message "Ecaml callback handling raised" (exn : Exn.t)] in (try Value.message_s sexp with | _ -> eprint_s sexp) ;; let registered_callbacks : Source_code_position.t String.Table.t = String.Table.create () let register (type callback) (t : callback t) here ~(f : callback) ~should_run_holding_async_lock = (match Hashtbl.find registered_callbacks t.name with | Some already_registered_at -> raise_s [%sexp "Multiple registrations for ecaml callback" , { name : string = t.name ; already_registered_at : Source_code_position.t ; repeat_registration_at : Source_code_position.t = here }] | None -> Hashtbl.set registered_callbacks ~key:t.name ~data:here); let with_lock f = if Scheduler.am_holding_lock scheduler then f () else Scheduler.with_lock scheduler f in let callback : callback = match t.arity with | Arity1 -> fun a1 -> (try if not should_run_holding_async_lock then f a1 else with_lock (fun () -> f a1) with | exn -> report_exn_when_calling_callback exn; raise exn) | Arity2 -> fun a1 a2 -> (try if not should_run_holding_async_lock then f a1 a2 else with_lock (fun () -> f a1 a2) with | exn -> report_exn_when_calling_callback exn; raise exn) in Stdlib.Callback.register t.name callback ;; let dispatch_function = { arity = Arity2; name = "dispatch_function" } let end_of_module_initialization = { arity = Arity1; name = "end_of_module_initialization" } ;; (** [no_active_env] is used when the C code detects that OCaml is attempting to call an Emacs function but there is no active env. It prints a message that includes an OCaml backtrace, which may be useful in debugging. *) let () = register { arity = Arity1; name = "no_active_env" } [%here] ~f:(fun () -> eprint_s [%message "Ecaml called with no active env" ~backtrace:(Backtrace.get () : Backtrace.t)]) ~should_run_holding_async_lock:true ;; let free_embedded_caml_values = { arity = Arity1; name = "free_embedded_caml_values" }
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>