Skip to content

rune-langium / lsp-server/src / createRuneLspServer

Function: createRuneLspServer()

ts
function createRuneLspServer(): RuneLspServer;

Defined in: packages/lsp-server/src/rune-dsl-server.ts:122

Create a fully-wired Rune DSL LSP server backed by @lspeasy/server.

Returns

RuneLspServer

A RuneLspServer ready for listen(transport).

Remarks

Initialization order (all synchronous before returning):

  1. LSPServer created with broad capability declarations
  2. createConnectionAdapter() wraps it to satisfy Langium's Connection interface
  3. Langium LSP services constructed (createDefaultSharedModule + Rune DSL modules)
  4. RuneDslValidator checks registered
  5. startLanguageServer(shared) wires all providers to connection handlers

The server responds to initialize requests only once per lifecycle — the connection adapter manages the Created → Initializing → Initialized state machine to avoid duplicate initialization errors.

Use When

  • Embedding a Rune DSL language server in a web application via WebSocket
  • Running a standalone LSP server process bridging to a VS Code / Theia client
  • Integration-testing LSP features (hover, completion, diagnostics)

Avoid When

  • Parsing .rosetta files in a script — use createRuneDslServices() and parse() / parseWorkspace() instead (no LSP overhead).
  • Creating multiple servers in the same process — each server maintains its own Langium workspace index; sharing a workspace across servers requires custom ServiceRegistry wiring.

Pitfalls

  • The workspace index is empty until the client sends textDocument/didOpen or workspace/didChangeWatchedFiles. Do NOT respond to semantic requests (hover, completion) before at least one didOpen has triggered a document build — results will be empty or stale.
  • Diagnostics are push-only (textDocument/publishDiagnostics notifications). There is no request-response path for diagnostics — the client must handle the notification asynchronously.
  • Langium batches diagnostic notifications; a burst of didChange events may not produce one notification per change. The final stable state is always published but intermediate states may be coalesced.

Example

ts
import { createRuneLspServer } from '@rune-langium/lsp-server';
import { WebSocketTransport } from '@lspeasy/core';

const lsp = createRuneLspServer();
const transport = new WebSocketTransport(webSocket);
await lsp.listen(transport);

Core packages released under MIT. Studio app released under FSL-1.1-ALv2.