Expand description
LSP adapter for increparse: a framework-agnostic bridge between the
Language Server Protocol and incremental multi-pass parsing.
The crate depends only on lsp_types — no server framework, no async
runtime, no I/O. You keep your server loop (lsp-server, tower-lsp,
async-lsp, a hand-rolled loop) and use this crate for the plumbing that
is easy to get wrong:
- Position encoding — LSP positions are
(line, character)pairs in UTF-8, UTF-16, or UTF-32 code units (negotiated via thepositionEncodingcapability); increparse spans are byte offsets.LineIndexconverts between the two, correctly, across multibyte text. Document— one open file: its text, its [Session], the client version, and the negotiated encoding.didOpen/didChangeevents go in; a run report comes out. Incremental change events are translated into byte-range [Edit]s so the tree reuses everything the edit did not touch.- Diagnostics — walk the settled tree, hand
Failedregions to your language-specific hook, and get back publishableDiagnostics with correctly converted ranges.
§Examples
use increparse::{Engine, Outcome, Pass, Schedule, SerialExecutor, Span, Status};
use increparse_lsp::{Document, PositionEncoding};
use lsp_types::Uri;
#[derive(Clone, Debug, PartialEq, Eq)]
enum Ctx { File }
struct Accept;
impl Pass for Accept {
type Ctx = Ctx;
fn parse(&self, _source: &str, _span: Span, _ctx: &Ctx) -> Outcome<Ctx> {
Outcome::Done
}
}
let uri: Uri = "file:///hello.txt".parse()?;
let mut doc = Document::open(uri, 0, "".into(), "héllo wörld".into(), PositionEncoding::Utf16, Ctx::File);
let engine = Engine::with((Accept,));
// The client edits "héllo" -> "héy": a same-length replace at byte 3.
// Translate the client's change events into `Edit`s via
// `Document::apply_changes`, then inspect the report:
let text = doc.text().to_string();
let report = engine.run(
&text,
doc.session_mut().tree_mut(),
&SerialExecutor,
&increparse::CancelToken::new(),
);
assert!(report.reached_fixpoint);A complete (small) server lives in examples/mini_lang_server.rs.
Modules§
- prelude
- The types you almost always want, in one glob (includes the core prelude).
Structs§
- Diagnostics
Options - Options for
diagnostics. - Document
- A single open document, bridging LSP change events and an increparse
Session. - Failed
Node - One parse-tree node offered to the user’s diagnostic hook.
- Line
Index - A line-start table over one text snapshot.
- Node
Label - A display name (and optional detail) for one tree node — what
SimpleLanguage::label_fnreturns to power the outline view. - Simple
Language - A
Languagebuilt from closures — the Rust equivalent of a Lua language definition.
Enums§
- Position
Encoding - The character-unit convention a client uses for
Position.character.
Traits§
- Language
- The language-specific half of a server.
Functions§
- diagnostics
- Builds diagnostics from a settled (or cancelled, or round-capped) parse.
- serve
- Runs a language server on stdio until the client sends
shutdown+exit. - serve_
on - Runs a full server lifecycle over an existing
connection: theinitializehandshake, then the message loop untilexit.
Type Aliases§
- Completion
Fn - The type of the
SimpleLanguage::completion_fnhook. - Definition
Fn - The type of the
SimpleLanguage::definition_fnhook. - Describe
Fn - The type of the
SimpleLanguage::describe_fnhook: describe a context in one sentence and the skeleton turns it into hover contents. - Documents
- The document store behind a running server: URI -> parsed document.
- Extra
Diagnostics Fn - The type of the
SimpleLanguage::extra_diagnosticshook. - HoverFn
- The type of the
SimpleLanguage::hover_fnhook (full control). - LabelFn
- The type of the
SimpleLanguage::label_fnhook. - Symbols
Fn - The type of the
SimpleLanguage::symbols_fnhook.