Documentation
¶
Overview ¶
Package lsp is the Language Server Protocol adapter behind the ports.LanguageService port (change 0026, ADR-0017).
This package is the only place in OpenPlus that knows the LSP wire protocol. Everything it hands the rest of the system is a neutral ports type: ports.Diagnostic, ports.Location, ports.Symbol. That is the hard rule of this change — no go.lsp.dev type may cross the port, exactly as no provider wire type escapes internal/provider (ADR-0005).
Two details drove the design, both discovered while considering whether to reuse internal/mcp's hand-rolled transport:
- LSP frames messages with Content-Length headers; MCP uses newline- delimited JSON. None of the MCP codec carries over.
- Diagnostics arrive *only* as server-initiated notifications. The MCP transport deliberately ignores those, so its read loop is not a template either. jsonrpc2.Conn.Go gives us the notification dispatch we need.
Positions: LSP counts lines and characters from zero; the neutral types count from one, which is what a compiler prints and a human reads. Conversion happens here, at the boundary, in both directions.
Index ¶
- type Client
- func (c *Client) Close() error
- func (c *Client) Definition(ctx context.Context, path string, line, col int) ([]ports.Location, error)
- func (c *Client) Diagnostics(path string) []ports.Diagnostic
- func (c *Client) DidOpen(ctx context.Context, path, text string) error
- func (c *Client) DocumentSymbols(ctx context.Context, path string) ([]ports.Symbol, error)
- func (c *Client) Hover(ctx context.Context, path string, line, col int) (string, error)
- func (c *Client) Initialized() bool
- func (c *Client) References(ctx context.Context, path string, line, col int) ([]ports.Location, error)
- type ClientConfig
- type Manager
- func (m *Manager) Definition(ctx context.Context, path string, line, col int) ([]ports.Location, error)
- func (m *Manager) Diagnostics(ctx context.Context, path string) ([]ports.Diagnostic, error)
- func (m *Manager) DocumentSymbols(ctx context.Context, path string) ([]ports.Symbol, error)
- func (m *Manager) Hover(ctx context.Context, path string, line, col int) (string, error)
- func (m *Manager) References(ctx context.Context, path string, line, col int) ([]ports.Location, error)
- func (m *Manager) Shutdown(context.Context) error
- func (m *Manager) Warnings() []string
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is one language-server connection.
func NewClient ¶
func NewClient(ctx context.Context, cfg ClientConfig) (*Client, error)
NewClient starts a language server and completes the initialize handshake. It returns once the server has answered initialize, so a caller that gets a Client back can immediately use it.
func (*Client) Close ¶
Close shuts the server down. It is idempotent so a deferred Close after an error path is safe, and it never blocks on a server that has stopped answering — a hung language server must not hang the agent.
func (*Client) Definition ¶
func (c *Client) Definition(ctx context.Context, path string, line, col int) ([]ports.Location, error)
Definition locates the definition of the symbol at a position.
func (*Client) Diagnostics ¶
func (c *Client) Diagnostics(path string) []ports.Diagnostic
Diagnostics returns the latest published diagnostics for a file.
func (*Client) DidOpen ¶
DidOpen tells the server about a file's contents. Calling it again for the same file sends didChange, which is what servers expect.
func (*Client) DocumentSymbols ¶
DocumentSymbols lists the declarations in a file.
func (*Client) Initialized ¶
Initialized reports whether the handshake completed.
type ClientConfig ¶
type ClientConfig struct {
// Root is the project directory the server is initialized against.
Root string
// Command and Args spawn the server. Ignored when RWC is set.
Command string
Args []string
// RWC is a test seam: when non-nil the client talks to it instead of
// spawning a process. Production callers leave it nil.
RWC io.ReadWriteCloser
}
ClientConfig describes one language server.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager routes code-intelligence questions to the language server that handles a file's extension, starting servers lazily. It implements ports.LanguageService.
Failure policy: a server that cannot start costs the user LSP for that one language, never the session. Every failure becomes a named warning, the failure is remembered so a missing binary is not re-forked on every call, and every surface degrades to an empty result with a nil error. An agent asking "what is broken in this file?" and getting "nothing I can see" is correct behavior when no server is available; an error there would abort a tool call over an optional enhancement.
func NewManager ¶
NewManager returns a Manager. It starts nothing: servers are spawned on first use of a file they handle.
func (*Manager) Definition ¶
func (m *Manager) Definition(ctx context.Context, path string, line, col int) ([]ports.Location, error)
Definition locates the symbol at a position.
func (*Manager) Diagnostics ¶
Diagnostics returns what the server last published for a file.
func (*Manager) DocumentSymbols ¶
DocumentSymbols lists the declarations in a file.
func (*Manager) References ¶
func (m *Manager) References(ctx context.Context, path string, line, col int) ([]ports.Location, error)
References finds uses of the symbol at a position.