lsp

package
v0.0.1-alpha.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 25, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

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:

  1. LSP frames messages with Content-Length headers; MCP uses newline- delimited JSON. None of the MCP codec carries over.
  2. 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

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

func (c *Client) Close() error

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

func (c *Client) DidOpen(ctx context.Context, path, text string) error

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

func (c *Client) DocumentSymbols(ctx context.Context, path string) ([]ports.Symbol, error)

DocumentSymbols lists the declarations in a file.

func (*Client) Hover

func (c *Client) Hover(ctx context.Context, path string, line, col int) (string, error)

Hover returns the server's description of the symbol at a position.

func (*Client) Initialized

func (c *Client) Initialized() bool

Initialized reports whether the handshake completed.

func (*Client) References

func (c *Client) References(ctx context.Context, path string, line, col int) ([]ports.Location, error)

References finds uses of the symbol at a position.

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

func NewManager(root string, cfg config.LSP) *Manager

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

func (m *Manager) Diagnostics(ctx context.Context, path string) ([]ports.Diagnostic, error)

Diagnostics returns what the server last published for a file.

func (*Manager) DocumentSymbols

func (m *Manager) DocumentSymbols(ctx context.Context, path string) ([]ports.Symbol, error)

DocumentSymbols lists the declarations in a file.

func (*Manager) Hover

func (m *Manager) Hover(ctx context.Context, path string, line, col int) (string, error)

Hover describes the symbol at a position.

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.

func (*Manager) Shutdown

func (m *Manager) Shutdown(context.Context) error

Shutdown stops every started server. Every client's Close is attempted even if an earlier one fails — a leaked language server is worse than a lost error message. Idempotent.

func (*Manager) Warnings

func (m *Manager) Warnings() []string

Warnings reports every server that could not be used, in the order the failures happened. The runtime surfaces these the way it surfaces MCP warnings.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL