Skip to main content

Module actor

Module actor 

Source
Expand description

Per-server actor (DESIGN.md §5.4 + §5.7). One tokio task owns the wire-side state for one (workspace, server-id) pair:

  • The pending-request table (RequestId → oneshot to the editor-side caller).
  • The negotiated Capabilities.
  • A monotonic JSON-RPC request-id counter.

Two helper tasks fan I/O in and out:

  • read_loop – reads Messages from LspReader and pushes them into an inbound channel.
  • write_loop – receives Messages on an outbound channel and writes them through LspWriter.

§Why three tasks

A single-task design works for a typewriter-pace editor but collapses under burst loads (a server emitting hundreds of $/progress notifications during indexing while the editor is also sending didChange per keystroke). Splitting reads and writes onto separate tasks lets the OS schedule them across cores; the actor task itself stays cheap (no I/O).

§Lifecycle

spawn runs the initialize handshake before returning a ServerHandle. Failure during handshake yields LspError::HandshakeFailed and tears the child process down via kill_on_drop.

ServerHandle::shutdown runs the LSP shutdown protocol: shutdown request → exit notification → wait for child exit. The actor task exits cleanly and all pending requests resolve with LspError::Cancelled.

Structs§

ServerHandle
Editor-facing handle to one running language-server actor.

Functions§

spawn
Spawn a language server from a ServerConfig.
spawn_with_io
Spawn the actor against pre-existing LspReader / LspWriter halves. Used by tests (mock server over a duplex pipe) and by future embedded transports (TCP, named pipe).
uri_from_path
uri_to_path
Convert a filesystem path to a file:// URI in the form LSP expects. lsp-types 0.97 dropped the url crate; we percent-encode manually for the small set of bytes that matter in a path (space → %20, etc.). Servers in practice tolerate plain file:///<path> without aggressive encoding. Inverse of uri_from_path. Strips the file:// scheme + percent-decodes the small set of bytes the encoder rewrites. Returns the path string (caller decides whether to coerce to PathBuf); None for non-file:// URIs.