Compare commits

..

6 commits

Author SHA1 Message Date
Simon Cruanes
83399e55c1 prepare for 0.11
Some checks failed
format / format (push) Has been cancelled
github pages / deploy (push) Has been cancelled
build / build4 (push) Has been cancelled
build / build5 (push) Has been cancelled
2026-04-07 21:14:03 -04:00
Simon Cruanes
b8f11ff433 optim ci 2026-04-07 21:06:41 -04:00
Simon Cruanes
5ae0d593ac
Merge pull request #62 from wintersteiger/christoph/allow-response-errors
Allow request handlers to return Response.Errors
2026-04-07 21:06:12 -04:00
Simon Cruanes
266b911bb3 format 2026-04-07 21:04:43 -04:00
Simon Cruanes
2e7a8f3482 faster CI 2026-04-07 21:04:43 -04:00
Christoph M. Wintersteiger
81f1fa0023
Allow request handlers to return Response.Errors 2026-03-24 17:28:03 +00:00
13 changed files with 71 additions and 73 deletions

17
.github/workflows/format.yml vendored Normal file
View file

@ -0,0 +1,17 @@
name: format
on:
push:
branches:
- main
pull_request:
jobs:
format:
name: format
runs-on: ubuntu-latest
container: ghcr.io/c-cube/c-cube-commmon/ci-4.14:latest
steps:
- uses: actions/checkout@v6
- run: opam exec -- make format-check

View file

@ -8,18 +8,13 @@ on:
jobs: jobs:
deploy: deploy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: ghcr.io/c-cube/c-cube-commmon/ci-doc-5.3:latest
steps: steps:
- uses: actions/checkout@main - uses: actions/checkout@v6
with:
submodules: 'recursive'
- uses: ocaml/setup-ocaml@v3
with:
ocaml-compiler: '5.2'
dune-cache: true
allow-prerelease-opam: true
- name: Deps - name: Deps
run: opam install odig linol linol-lwt run: opam install linol linol-lwt
- name: Build - name: Build
run: opam exec -- odig odoc --cache-dir=_doc/ linol linol-lwt || (odig log -e ; exit 1) run: opam exec -- odig odoc --cache-dir=_doc/ linol linol-lwt || (odig log -e ; exit 1)

View file

@ -6,52 +6,25 @@ on:
pull_request: pull_request:
jobs: jobs:
build4: build4:
strategy: runs-on: ubuntu-latest
matrix: container: ghcr.io/c-cube/c-cube-commmon/ci-4.14:latest
os:
- ubuntu-latest
ocaml-compiler:
- 4.14.x
runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@main - uses: actions/checkout@v6
with: with:
submodules: 'recursive' submodules: 'recursive'
- uses: ocaml/setup-ocaml@v3
with:
ocaml-compiler: ${{ matrix.ocaml-compiler }}
dune-cache: true
allow-prerelease-opam: true
- run: opam pin -n . - run: opam pin -n .
- run: opam depext -yt linol linol-lwt
- run: opam install linol linol-lwt --deps-only -t - run: opam install linol linol-lwt --deps-only -t
- run: opam exec -- dune build -p linol,linol-lwt - run: opam exec -- dune build -p linol,linol-lwt
- run: opam exec -- dune runtest -p linol,linol-lwt - run: opam exec -- dune runtest -p linol,linol-lwt
if: ${{ matrix.os == 'ubuntu-latest' }}
build5: build5:
strategy: runs-on: ubuntu-latest
matrix: container: ghcr.io/c-cube/c-cube-commmon/ci-5.4:latest
os:
- ubuntu-latest
#- macos-latest
#- windows-latest
ocaml-compiler:
- 5.1.x
- 5.2.x
- 5.3.x
runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@main - uses: actions/checkout@v6
with: with:
submodules: 'recursive' submodules: 'recursive'
- uses: ocaml/setup-ocaml@v3
with:
ocaml-compiler: ${{ matrix.ocaml-compiler }}
dune-cache: true
allow-prerelease-opam: true
- run: opam pin -n . - run: opam pin -n .
- run: opam depext -yt linol linol-lwt linol-eio
- run: opam install -t . --deps-only - run: opam install -t . --deps-only
- run: opam exec -- dune build - run: opam exec -- dune build
- run: opam exec -- dune runtest - run: opam exec -- dune runtest
if: ${{ matrix.os == 'ubuntu-latest' }}

View file

@ -3,6 +3,9 @@
- breaking: the Eio library now needs the output channel to be paired with - breaking: the Eio library now needs the output channel to be paired with
an `Eio.Mutex.t` to prevent race conditions (#58) an `Eio.Mutex.t` to prevent race conditions (#58)
- Allow request handlers to return Response.Errors
- bring back `Linol_eio.spawn` for logging uncaught exceptions
- Make template-eio handle requests concurrently
# 0.10 # 0.10

View file

@ -13,9 +13,12 @@ clean:
doc: doc:
@dune build @doc @dune build @doc
fmt: format:
@dune build @fmt --auto-promote @dune build @fmt --auto-promote
format-check:
@dune build $(DUNE_OPTS) @fmt --display=quiet
update-submodules: update-submodules:
@git submodule update --init @git submodule update --init

View file

@ -8,7 +8,7 @@
(name linol) (name linol)
(version 0.10) (version 0.11)
(license MIT) (license MIT)

View file

@ -37,7 +37,7 @@ let diagnostics (_state : state_after_processing) : Lsp.Types.Diagnostic.t list
so that users only need to override methods that they want the server to so that users only need to override methods that they want the server to
actually meaningfully interpret and respond to. actually meaningfully interpret and respond to.
*) *)
class lsp_server ~(sw: Eio.Switch.t) = class lsp_server ~(sw : Eio.Switch.t) =
object (self) object (self)
inherit Linol_eio.Jsonrpc2.server inherit Linol_eio.Jsonrpc2.server

View file

@ -1,6 +1,6 @@
# This file is generated by dune, edit dune-project instead # This file is generated by dune, edit dune-project instead
opam-version: "2.0" opam-version: "2.0"
version: "0.10" version: "0.11"
synopsis: "LSP server library (with Eio for concurrency)" synopsis: "LSP server library (with Eio for concurrency)"
maintainer: ["Simon Cruanes"] maintainer: ["Simon Cruanes"]
authors: ["Nick Hu"] authors: ["Nick Hu"]

View file

@ -1,6 +1,6 @@
# This file is generated by dune, edit dune-project instead # This file is generated by dune, edit dune-project instead
opam-version: "2.0" opam-version: "2.0"
version: "0.10" version: "0.11"
synopsis: "LSP server library (with Lwt for concurrency)" synopsis: "LSP server library (with Lwt for concurrency)"
maintainer: ["Simon Cruanes"] maintainer: ["Simon Cruanes"]
authors: ["Simon Cruanes"] authors: ["Simon Cruanes"]

View file

@ -1,6 +1,6 @@
# This file is generated by dune, edit dune-project instead # This file is generated by dune, edit dune-project instead
opam-version: "2.0" opam-version: "2.0"
version: "0.10" version: "0.11"
synopsis: "LSP server library" synopsis: "LSP server library"
maintainer: ["Simon Cruanes"] maintainer: ["Simon Cruanes"]
authors: ["Simon Cruanes"] authors: ["Simon Cruanes"]

View file

@ -54,12 +54,11 @@ end
(** Spawn function. *) (** Spawn function. *)
let spawn ~sw f = let spawn ~sw f =
Eio.Fiber.fork ~sw (fun () -> Eio.Fiber.fork ~sw (fun () ->
try try f ()
f () with exn ->
with exn -> Printf.eprintf "uncaught exception in `spawn`:\n%s\n%!"
Printf.eprintf "uncaught exception in `spawn`:\n%s\n%!" (Printexc.to_string exn);
(Printexc.to_string exn); raise exn)
raise exn)
include Lsp.Types include Lsp.Types
include IO_eio include IO_eio

View file

@ -228,10 +228,7 @@ module Make (IO : IO) : S with module IO = IO = struct
| Ok reply -> | Ok reply ->
let reply_json = Lsp.Client_request.yojson_of_result r reply in let reply_json = Lsp.Client_request.yojson_of_result r reply in
Jsonrpc.Response.ok id reply_json Jsonrpc.Response.ok id reply_json
| Error message -> | Error err -> Jsonrpc.Response.error id err
Jsonrpc.Response.error id
(Jsonrpc.Response.Error.make
~code:Jsonrpc.Response.Error.Code.InternalError ~message ())
in in
send_response self response send_response self response

View file

@ -61,7 +61,7 @@ module Make (IO : IO) = struct
server_request:send_request -> server_request:send_request ->
id:Req_id.t -> id:Req_id.t ->
'a Lsp.Client_request.t -> 'a Lsp.Client_request.t ->
('a, string) result IO.t ('a, Jsonrpc.Response.Error.t) result IO.t
(** Method called to handle client requests. (** Method called to handle client requests.
@param notify_back @param notify_back
an object used to reply to the client, send progress messages, an object used to reply to the client, send progress messages,
@ -379,21 +379,31 @@ module Make (IO : IO) = struct
server_request:_ -> server_request:_ ->
id:Req_id.t -> id:Req_id.t ->
r Lsp.Client_request.t -> r Lsp.Client_request.t ->
(r, string) result IO.t = (r, Jsonrpc.Response.Error.t) result IO.t =
fun ~notify_back ~server_request ~id (r : _ Lsp.Client_request.t) -> fun ~notify_back ~server_request ~id (r : _ Lsp.Client_request.t) ->
Trace.with_span ~__FILE__ ~__LINE__ "linol.on-request" Trace.with_span ~__FILE__ ~__LINE__ "linol.on-request"
@@ fun _sp : (r, string) result IO.t -> @@ fun _sp : (r, Jsonrpc.Response.Error.t) result IO.t ->
(* handler to catch all errors *) (* handler to catch all errors *)
let try_catch : (unit -> (r, _) result IO.t) -> (r, _) result IO.t = let try_catch :
(unit -> (r, Jsonrpc.Response.Error.t) result IO.t) ->
(r, Jsonrpc.Response.Error.t) result IO.t =
fun f -> fun f ->
IO.catch f (fun exn bt -> IO.catch f (fun (exn : exn) bt ->
let msg = match exn with
spf "LSP request handler failed with %s\n%s" | Linol_jsonrpc.Jsonrpc.Response.Error.E e ->
(Printexc.to_string exn) IO.return @@ Error e
(Printexc.raw_backtrace_to_string bt) | _ ->
in let msg =
Log.err (fun k -> k "%s" msg); spf "LSP request handler failed with %s\n%s"
IO.return @@ Error msg) (Printexc.to_string exn)
(Printexc.raw_backtrace_to_string bt)
in
Log.err (fun k -> k "%s" msg);
IO.return
@@ Error
(Jsonrpc.Response.Error.make
~code:Jsonrpc.Response.Error.Code.InternalError
~message:msg ()))
in in
try_catch @@ fun () -> try_catch @@ fun () ->
@ -737,7 +747,8 @@ module Make (IO : IO) = struct
in in
let new_doc : Lsp.Text_document.t = let new_doc : Lsp.Text_document.t =
Lsp.Text_document.apply_content_changes old_doc c Lsp.Text_document.apply_content_changes ~version:doc.version
old_doc c
in in
let new_st : doc_state = let new_st : doc_state =