package sturgeon
A toolkit for communicating with Emacs
Install
Dune Dependency
Authors
Maintainers
Sources
v0.4.2.tar.gz
md5=16f984c347be593eb590c0ad0611ee08
sha512=cfe091eeb36b14029ae1560a780ad099239de8f80f9c942dc6b0ef1b08bf47add0f29a575d8127ed4648cb3ab27f3ca0d520befa55aeb22411dcfca545e0bd44
doc/src/sturgeon.recipes_server/sturgeon_recipes_server.ml.html
Source file sturgeon_recipes_server.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
open Sturgeon type server = { client: unit -> (Session.t option * (Session.t -> unit) option); mutable socket: Unix.file_descr option; mutable clients: (Unix.file_descr) list; connections: (Unix.file_descr, (unit -> Sexp.basic option) * Session.output * Session.status) Hashtbl.t; } let server ~client name = let dir = Filename.concat (Filename.get_temp_dir_name ()) (Printf.sprintf "sturgeon.%d" (Unix.getuid ())) in if not (Sys.file_exists dir) then Unix.mkdir dir 0o770; let name = Filename.concat dir (Printf.sprintf "%s.%d.sturgeon" name (Unix.getpid ())) in let socket = Unix.socket Unix.PF_UNIX Unix.SOCK_STREAM 0 in let addr = Unix.ADDR_UNIX name in Unix.bind socket addr; at_exit (fun () -> Unix.unlink name); Unix.listen socket 3; { socket = Some socket; clients = []; connections = Hashtbl.create 7; client } let accept server = match server.socket with | None -> () | Some socket -> let client, _ = Unix.accept socket in let oc = Unix.out_channel_of_descr client in let olock = Mutex.create () in let send sexp = Mutex.lock olock; try Sexp.tell_sexp (output_string oc) sexp; output_char oc '\n'; flush oc; Mutex.unlock olock; with exn -> Mutex.unlock olock; raise exn in let greetings, cogreetings = server.client () in let received, status = Session.connect ?greetings ?cogreetings send in let stdin = Sexp.of_file_descr ~on_read:ignore client in server.clients <- client :: server.clients; Hashtbl.replace server.connections client (stdin, received, status) let filter_fd server fd = if Hashtbl.mem server.connections fd then true else begin Unix.close fd; false end let rec main_loop server = match server.socket with | None -> () | Some socket -> server.clients <- List.filter (filter_fd server) server.clients; match Unix.select (socket :: server.clients) [] [] 1.0 with | exception Unix.Unix_error (Unix.EINTR, _, _) -> main_loop server | (r, _, _) -> let rec pump fd (stdin, received, status) = match stdin () with | None -> Hashtbl.remove server.connections fd | exception (Sys_error _) -> Hashtbl.remove server.connections fd | Some sexp -> begin try received sexp; with _ -> () end; match Unix.select [fd] [] [] 0.0 <> ([],[],[]) with | true -> pump fd (stdin, received, status) | false -> () | exception Unix.Unix_error (Unix.EINTR, _, _) -> () in let process fd = if fd = socket then try accept server with _ -> () else pump fd (Hashtbl.find server.connections fd) in List.iter process r; main_loop server let main_loop ?(keep_sigpipe=false) server = if not keep_sigpipe then (try ignore (Sys.signal Sys.sigpipe Sys.Signal_ignore) with _ -> ()); main_loop server let stop_server server = match server.socket with | None -> () | Some socket -> server.socket <- None; server.clients <- []; let clients = server.clients in Hashtbl.clear server.connections; List.iter Unix.close clients; Unix.close socket let text_server name f = server ~client:(fun () -> let greetings, shell = Stui.buffer_greetings () in Some greetings, Some (fun args -> f ~args shell) ) name
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>