Discussing the design for LSP support
Hi! I am interested in adding LSP support to Grace. I got started by writing a function that simply converts a Grace-style diagnostic into an LSP diagnostic. Most of this is straightforward, but there is something I'd like to discuss.
Using Grace's API, one can create diagnostics with multiple primary labels, but LSP diagnostics are specified to only have one main range, with optional additional related information. Do you have any thoughts on this design mismatch?
I am also interested in discussing more ambitious plans for LSP integration!
Hey 👋
Perhaps we should attach a location with the main message that we write for a diagnostic:
type 'code t = {
severity : Severity.t
; message : Message.t With_range.t
; ...
}
For now, I'd probably stick to the 'locus' range -- the earliest primary label range. This would at least be consistent with the location info displayed by Grace's ANSI renderer.
As for more ambitious plans for LSP integration, the first step I had in mind was a Grace_lsp library, which just adds support for converting between Grace's types and LSP types.
Sidenote, the lsp library available on opam is a dependency of ocaml-lsp-server. Because of that, if Grace starts depending on lsp, then a given version of Grace will lock a specific version of ocaml-lsp.
Because of that issue, I ended up PRing linol to vendor lsp.
The issue now is that, if someone wants to use Linol together with Grace, the lsp types wouldn't match (whether Grace vendors Lsp or not).
How about introducing a signature like Lsp_constructors.S which describes a series of constructors to build a diagnostic, and then whatever Grace does is parametric on a module that implements that interface (that is, any copy of the Lsp library)?