Documentation
¶
Overview ¶
Package lsp is memcode's resident Language Server Protocol client — the "give the agent eyes" layer. It speaks JSON-RPC 2.0 over a language server's stdio (gopls, typescript-language-server, pyright), holding the server RESIDENT for the session so diagnostics are incremental (milliseconds, not a full re-typecheck) and semantic queries (definition / references / hover) are available. This is the capability no amount of grep + build gives, and the only static type-error source for TS/Python.
Model (following Claude Code): DETECT AND CONNECT. A server is used only when its binary is on PATH; nothing is bundled or auto-installed. The valuable operations for an agent are diagnostics, definition, and references — completion is deliberately not implemented.
Index ¶
- func PathToURI(path string) string
- func ServerBins() map[string]string
- func URIToPath(uri string) string
- type Client
- func (c *Client) Close()
- func (c *Client) Definition(ctx context.Context, uri string, pos Position) ([]Location, error)
- func (c *Client) Diagnostics(uri string) []Diagnostic
- func (c *Client) DidChange(uri string, version int, text string) error
- func (c *Client) DidOpen(uri, languageID, text string) error
- func (c *Client) DocumentSymbol(ctx context.Context, uri string) ([]DocumentSymbol, error)
- func (c *Client) Hover(ctx context.Context, uri string, pos Position) (string, error)
- func (c *Client) Initialize(ctx context.Context, root string) error
- func (c *Client) References(ctx context.Context, uri string, pos Position) ([]Location, error)
- func (c *Client) WaitDiagnostics(ctx context.Context, uri string, timeout time.Duration) []Diagnostic
- type Diagnostic
- type DocumentSymbol
- type EnclosingSymbol
- type FileSymbol
- type Location
- type Manager
- func (m *Manager) Close()
- func (m *Manager) Definition(ctx context.Context, path string, line, col int) ([]Location, bool, error)
- func (m *Manager) DiagnoseAfterEdit(ctx context.Context, path string) (diags []Diagnostic, ok bool, err error)
- func (m *Manager) Diagnostics(ctx context.Context, path string) (diags []Diagnostic, ok bool, err error)
- func (m *Manager) EnclosingSymbol(ctx context.Context, path string, line, col int) (EnclosingSymbol, bool, error)
- func (m *Manager) FileSymbols(ctx context.Context, path string) ([]FileSymbol, bool, error)
- func (m *Manager) FormatLocations(locs []Location) string
- func (m *Manager) Hover(ctx context.Context, path string, line, col int) (string, bool, error)
- func (m *Manager) InstallHint(path string) string
- func (m *Manager) References(ctx context.Context, path string, line, col int) ([]Location, bool, error)
- func (m *Manager) Supported(path string) (lang string, ok bool)
- type Position
- type Range
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ServerBins ¶
ServerBins reports the registry's language → server binary (for doctor's missing-server check). javascript shares typescript's binary; callers that want one row per binary can dedupe on the value.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a JSON-RPC 2.0 client over one language server's stdio. It is created by the manager per language and reused across a session. Safe for concurrent Requests; the write side is mutex-guarded and responses are demuxed by id.
func (*Client) Close ¶
func (c *Client) Close()
Close shuts the server down (best-effort shutdown/exit, then kill).
func (*Client) Definition ¶
Definition returns where the symbol at pos is defined. Handles the server returning a single Location or an array (both are valid per the spec).
func (*Client) Diagnostics ¶
func (c *Client) Diagnostics(uri string) []Diagnostic
Diagnostics returns the latest diagnostics the server pushed for uri. Callers that just opened/changed a file should give the server a moment to publish (see WaitDiagnostics).
func (*Client) DidChange ¶
DidChange tells the server a document's full content changed (full-sync) — sent after an edit so its diagnostics reflect the new text. version must increase per document.
func (*Client) DidOpen ¶
DidOpen tells the server about a document's content — required before it will produce diagnostics or answer position queries for that file.
func (*Client) DocumentSymbol ¶
DocumentSymbol returns the file's symbol tree. Handles both the hierarchical DocumentSymbol[] result (gopls/tsserver/pyright) and the flat SymbolInformation[] fallback.
func (*Client) Hover ¶
Hover returns the type/signature/doc for the symbol at pos, flattened to text.
func (*Client) Initialize ¶
Initialize runs the LSP handshake with the workspace root, then sends `initialized`. The declared client capabilities are the minimal set our operations use.
func (*Client) References ¶
References returns every use of the symbol at pos (including its declaration).
func (*Client) WaitDiagnostics ¶
func (c *Client) WaitDiagnostics(ctx context.Context, uri string, timeout time.Duration) []Diagnostic
WaitDiagnostics polls for diagnostics on uri up to timeout — diagnostics arrive as an async push after didOpen, so a caller that needs them right after opening waits briefly. Returns whatever is present at the deadline (empty means "clean" once the server settled).
type Diagnostic ¶
type Diagnostic struct {
Range Range `json:"range"`
Severity int `json:"severity"` // 1 error, 2 warning, 3 info, 4 hint
Code any `json:"code"`
Source string `json:"source"`
Message string `json:"message"`
}
Diagnostic is one problem the server reports for a document.
func (Diagnostic) SeverityLabel ¶
func (d Diagnostic) SeverityLabel() string
SeverityLabel renders the numeric severity as text.
type DocumentSymbol ¶
type DocumentSymbol struct {
Name string `json:"name"`
Kind int `json:"kind"`
Range Range `json:"range"`
SelectionRange Range `json:"selectionRange"`
Children []DocumentSymbol `json:"children,omitempty"`
}
DocumentSymbol is a named symbol in a file (LSP documentSymbol). Range is the full span (declaration + body); SelectionRange is the name token. Children nest (a method inside a type). Used to attribute a reference to the function/method that contains it.
type EnclosingSymbol ¶
type EnclosingSymbol struct {
Name string
Kind int
Path string // absolute file path (as queried)
DefLine int // 1-based line of the symbol name (its selectionRange start)
DefCol int // 1-based column
}
EnclosingSymbol is the named symbol whose body contains a position — used to attribute a reference to the function/method that contains it, for call-graph / impact analysis.
type FileSymbol ¶
type FileSymbol struct {
Name string
Kind int // LSP SymbolKind
Line int // 1-based full-range start
EndLine int // 1-based full-range end
SelLine int // 1-based name-token line
Depth int // 0 = top level, 1 = member (a class's method), …
}
FileSymbol is one declaration from a file's LSP symbol tree, flattened for consumers that want a per-file symbol list (the repo map) rather than the enclosing-position query EnclosingSymbol answers.
type Location ¶
Location is a range within a document (uri) — the shape definition/references return.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager owns one resident language server per language for a workspace, started lazily and reused for the session. It is the session-facing surface (Diagnostics/Definition/ References/Hover by file path). Nil-safe: a zero Manager degrades to "no LSP".
func NewManager ¶
NewManager returns a Manager rooted at the workspace. Servers are started on first use.
func (*Manager) Close ¶
func (m *Manager) Close()
Close shuts every resident server down (call on session end).
func (*Manager) Definition ¶
func (m *Manager) Definition(ctx context.Context, path string, line, col int) ([]Location, bool, error)
Definition/References/Hover resolve the symbol at a 1-based line/col (the human/editor convention) — converted to LSP's 0-based position here.
func (*Manager) DiagnoseAfterEdit ¶
func (m *Manager) DiagnoseAfterEdit(ctx context.Context, path string) (diags []Diagnostic, ok bool, err error)
DiagnoseAfterEdit re-syncs a file that was just edited on disk (didChange with the new content, or didOpen if the server hasn't seen it yet), then waits for the server's fresh diagnostics. This is the "sees the error immediately, fixes it the same turn" loop. ok=false when no resident server serves the file.
func (*Manager) Diagnostics ¶
func (m *Manager) Diagnostics(ctx context.Context, path string) (diags []Diagnostic, ok bool, err error)
Diagnostics returns the resident server's diagnostics for a file (opening it first and waiting briefly for the async push). ok=false means no server is available for it.
func (*Manager) EnclosingSymbol ¶
func (m *Manager) EnclosingSymbol(ctx context.Context, path string, line, col int) (EnclosingSymbol, bool, error)
EnclosingSymbol resolves the most-specific symbol containing a 1-based line/col. ok=false when no resident server serves the file or nothing encloses the position.
func (*Manager) FileSymbols ¶
FileSymbols returns the file's declarations via textDocument/documentSymbol, flattened two levels deep (top-level + members — grandchildren are locals and fields, noise for a repo overview). ok=false when no resident server serves the file's language.
func (*Manager) FormatLocations ¶
FormatLocations renders locations as repo-relative file:line references for the model.
func (*Manager) InstallHint ¶
InstallHint returns the binary a user must install to enable LSP for path's language.