gleamunison/lsp

Minimal LSP server: diagnostics over stdio, Content-Length framed. One function per verb, all pure: JSON body in, list of reply bodies out. The stdio pump (cli_lsp) is the only impure part.

Types

One diagnostic: LSP wants 0-based positions; our spans are 1-based.

pub type Diagnostic {
  Diagnostic(line: Int, col: Int, message: String)
}

Constructors

  • Diagnostic(line: Int, col: Int, message: String)

Values

pub fn decode_framed(
  buffer: String,
) -> Result(#(String, String), Nil)

Split one Content-Length framed message off a buffer. Error means incomplete: the pump keeps reading and retries.

pub fn diagnose(source: String) -> List(Diagnostic)

Parse + elaborate source text, returning one diagnostic per error. Pure: no compilation, no loading, no handlers. Spans come through as 1-based from elaboration; LSP gets them 0-based.

pub fn encode_frame(body: String) -> String
pub fn handle_message(
  body: String,
  state: lsp_types.State,
) -> #(List(String), lsp_types.State)

Handle one JSON-RPC body. Returns reply bodies (responses and notifications) to frame and write, plus the new server state.

✨ Search Document