Core Concepts

A go-lsp server is a handler object plus optional server configuration.

Lifecycle Is Required

Every server implements LifecycleHandler:

type LifecycleHandler interface {
    Initialize(context.Context, *lsp.InitializeParams) (*lsp.InitializeResult, error)
    Shutdown(context.Context) error
}

Everything Else Is Opt-in

Implement a feature interface and go-lsp registers the method and advertises support. For example, implementing HoverHandler enables textDocument/hover.

func (h *Handler) Hover(ctx context.Context, params *lsp.HoverParams) (*lsp.Hover, error) {
    return &lsp.Hover{
        Contents: lsp.MarkupContent{Kind: lsp.Markdown, Value: "hello"},
    }, nil
}

Client Access

Implement ClientHandler when your server needs to send diagnostics, messages, progress, or client requests.

func (h *Handler) SetClient(client *server.Client) {
    h.client = client
}

Custom Methods

Use custom methods for server-specific extensions outside the LSP spec.

srv.HandleMethod("custom/status", func(ctx context.Context, params json.RawMessage) (any, error) {
    return map[string]string{"status": "ok"}, nil
})