lsp

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package lsp is the protocol glue for `rune lsp`: a JSON-RPC 2.0 server over stdio speaking a minimal typed subset of LSP 3.17. It contains no language logic — it converts between LSP payloads and the analysis/language layers, converts byte spans to UTF-16 positions (convert.go), and enforces that stdout carries protocol bytes only (spec FR-011, FR-012, FR-014). It runs nothing (FR-028).

Index

Constants

View Source
const (
	ParseError       = -32700
	InvalidRequest   = -32600
	MethodNotFound   = -32601
	InvalidParams    = -32602
	InternalError    = -32603
	RequestCancelled = -32800
)

JSON-RPC 2.0 error codes used by the server (LSP base protocol).

View Source
const (
	SyncNone        = 0
	SyncFull        = 1
	SyncIncremental = 2
)

TextDocumentSyncKind values.

View Source
const (
	SeverityError   = 1
	SeverityWarning = 2
)

LSP DiagnosticSeverity values.

View Source
const (
	CIKMethod   = 2
	CIKFunction = 3
	CIKVariable = 6
	CIKKeyword  = 14
	CIKProperty = 10
	CIKEnum     = 13
)

LSP CompletionItemKind values (subset).

View Source
const (
	SKModule    = 2
	SKNamespace = 3
	SKProperty  = 7
	SKFunction  = 12
	SKVariable  = 13
)

LSP SymbolKind values (subset).

Variables

This section is empty.

Functions

This section is empty.

Types

type CompletionItem

type CompletionItem struct {
	Label         string `json:"label"`
	Kind          int    `json:"kind,omitempty"`
	Detail        string `json:"detail,omitempty"`
	Documentation string `json:"documentation,omitempty"`
}

CompletionItem is one suggestion returned to the client.

type CompletionOptions

type CompletionOptions struct {
	TriggerCharacters []string `json:"triggerCharacters,omitempty"`
}

type CompletionParams

type CompletionParams struct {
	TextDocument TextDocumentIdentifier `json:"textDocument"`
	Position     Position               `json:"position"`
}

CompletionParams is the textDocument/completion request (position-based; the optional completion context is ignored).

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn is a framed JSON-RPC connection over a reader/writer pair (stdin/stdout for the LSP). Writes are serialized so concurrent responses and server notifications never interleave on the wire.

func NewConn

func NewConn(r io.Reader, w io.Writer) *Conn

NewConn wraps a reader/writer as a framed JSON-RPC connection.

func (*Conn) Read

func (c *Conn) Read() (*Message, error)

Read reads one Content-Length-framed message. It returns io.EOF at end of input. A malformed header or body yields a non-nil error but never panics.

func (*Conn) Write

func (c *Conn) Write(m *Message) error

Write frames and writes one message.

type Diagnostic

type Diagnostic struct {
	Range              Range                          `json:"range"`
	Severity           int                            `json:"severity"` // 1 error, 2 warning
	Code               string                         `json:"code,omitempty"`
	Source             string                         `json:"source,omitempty"`
	Message            string                         `json:"message"`
	RelatedInformation []DiagnosticRelatedInformation `json:"relatedInformation,omitempty"`
}

type DiagnosticRelatedInformation

type DiagnosticRelatedInformation struct {
	Location Location `json:"location"`
	Message  string   `json:"message"`
}

type DidChangeTextDocumentParams

type DidChangeTextDocumentParams struct {
	TextDocument   VersionedTextDocumentIdentifier  `json:"textDocument"`
	ContentChanges []TextDocumentContentChangeEvent `json:"contentChanges"`
}

type DidChangeWatchedFilesParams

type DidChangeWatchedFilesParams struct {
	Changes []FileEvent `json:"changes"`
}

type DidChangeWatchedFilesRegistrationOptions

type DidChangeWatchedFilesRegistrationOptions struct {
	Watchers []FileSystemWatcher `json:"watchers"`
}

type DidCloseTextDocumentParams

type DidCloseTextDocumentParams struct {
	TextDocument TextDocumentIdentifier `json:"textDocument"`
}

type DidOpenTextDocumentParams

type DidOpenTextDocumentParams struct {
	TextDocument TextDocumentItem `json:"textDocument"`
}

type DidSaveTextDocumentParams

type DidSaveTextDocumentParams struct {
	TextDocument TextDocumentIdentifier `json:"textDocument"`
}

type DocumentFormattingParams

type DocumentFormattingParams struct {
	TextDocument TextDocumentIdentifier `json:"textDocument"`
}

type DocumentSymbol

type DocumentSymbol struct {
	Name           string           `json:"name"`
	Detail         string           `json:"detail,omitempty"`
	Kind           int              `json:"kind"`
	Range          Range            `json:"range"`
	SelectionRange Range            `json:"selectionRange"`
	Children       []DocumentSymbol `json:"children,omitempty"`
}

DocumentSymbol is a hierarchical outline node. Range covers the whole symbol; SelectionRange (⊆ Range) is what navigation selects.

type DocumentSymbolParams

type DocumentSymbolParams struct {
	TextDocument TextDocumentIdentifier `json:"textDocument"`
}

type FileEvent

type FileEvent struct {
	URI  string `json:"uri"`
	Type int    `json:"type"` // 1 created, 2 changed, 3 deleted
}

type FileSystemWatcher

type FileSystemWatcher struct {
	GlobPattern string `json:"globPattern"`
}

type Hover

type Hover struct {
	Contents MarkupContent `json:"contents"`
	Range    *Range        `json:"range,omitempty"`
}

Hover is the result of textDocument/hover.

type InitializeParams

type InitializeParams struct {
	ProcessID        int               `json:"processId,omitempty"`
	RootURI          string            `json:"rootUri,omitempty"`
	WorkspaceFolders []WorkspaceFolder `json:"workspaceFolders,omitempty"`
}

InitializeParams is the (partial) client initialize request. Only the fields the server uses are modeled; unknown fields are ignored by encoding/json.

type InitializeResult

type InitializeResult struct {
	Capabilities ServerCapabilities `json:"capabilities"`
	ServerInfo   ServerInfo         `json:"serverInfo"`
}

type LineIndex

type LineIndex struct {
	// contains filtered or unexported fields
}

LineIndex converts between Rune's byte-oriented source offsets/columns and LSP's line + UTF-16-character positions. It is the single conversion layer for the server (spec FR-006): building it per document version keeps the mapping correct across the full unicode/line-ending matrix (ASCII, multi-byte, emoji/surrogate pairs, combining marks, CRLF, LF, empty lines, EOF).

func NewLineIndex

func NewLineIndex(text string) *LineIndex

NewLineIndex builds an index for text. Line starts are the byte after each '\n'; a '\r' before '\n' stays part of the preceding line's bytes but is never counted as content because real spans point at content boundaries.

func (*LineIndex) ByteOffsetToPosition

func (ix *LineIndex) ByteOffsetToPosition(offset int) Position

ByteOffsetToPosition maps a byte offset to an LSP position. Out-of-range offsets are clamped so the function is total (never panics).

func (*LineIndex) PositionToByteOffset

func (ix *LineIndex) PositionToByteOffset(pos Position) (int, error)

PositionToByteOffset maps an LSP position to a byte offset. The offset is always valid (clamped); an error is returned only when the line is beyond the document, so callers may either honor it or use the clamped offset.

func (*LineIndex) SpanToRange

func (ix *LineIndex) SpanToRange(span token.Span) Range

SpanToRange converts a Rune source span to an LSP range.

type Location

type Location struct {
	URI   string `json:"uri"`
	Range Range  `json:"range"`
}

type MarkupContent

type MarkupContent struct {
	Kind  string `json:"kind"` // "markdown" | "plaintext"
	Value string `json:"value"`
}

type Message

type Message struct {
	JSONRPC string           `json:"jsonrpc"`
	ID      *json.RawMessage `json:"id,omitempty"`
	Method  string           `json:"method,omitempty"`
	Params  json.RawMessage  `json:"params,omitempty"`
	Result  json.RawMessage  `json:"result,omitempty"`
	Error   *ResponseError   `json:"error,omitempty"`
}

Message is a JSON-RPC 2.0 message. A request has ID + Method; a notification has Method and no ID; a response has ID + (Result | Error).

func NewErrorResponse

func NewErrorResponse(id *json.RawMessage, code int, msg string) *Message

NewErrorResponse builds an error response for the given request id.

func NewNotification

func NewNotification(method string, params any) (*Message, error)

NewNotification builds a server-to-client notification.

func NewResponse

func NewResponse(id *json.RawMessage, result any) (*Message, error)

NewResponse builds a success response for the given request id and result.

func (*Message) IsNotification

func (m *Message) IsNotification() bool

IsNotification reports whether the message is a notification (no ID).

func (*Message) IsRequest

func (m *Message) IsRequest() bool

IsRequest reports whether the message is a request (has ID and Method).

type Options

type Options struct {
	// Version is reported in the initialize response's serverInfo.
	Version string
	// LogWriter receives server logs (stderr or a file); never stdout.
	LogWriter io.Writer
	// Debounce is the delay before analyzing after a change (default 100ms).
	Debounce time.Duration
}

Options configures a Server.

type Position

type Position struct {
	Line      uint32 `json:"line"`
	Character uint32 `json:"character"`
}

Position is an LSP text position: a 0-based line and a 0-based character offset counted in UTF-16 code units (LSP's default positionEncoding).

type PublishDiagnosticsParams

type PublishDiagnosticsParams struct {
	URI string `json:"uri"`
	// Version is the document version the diagnostics were computed for. It is
	// optional per LSP; omitted (nil) rather than sent as a misleading 0 for
	// files that are not open, since version-checking clients discard a payload
	// whose version does not match the buffer they hold.
	Version     *int         `json:"version,omitempty"`
	Diagnostics []Diagnostic `json:"diagnostics"`
}

type Range

type Range struct {
	Start Position `json:"start"`
	End   Position `json:"end"`
}

Range is an LSP half-open range [Start, End).

type Registration

type Registration struct {
	ID              string `json:"id"`
	Method          string `json:"method"`
	RegisterOptions any    `json:"registerOptions,omitempty"`
}

type RegistrationParams

type RegistrationParams struct {
	Registrations []Registration `json:"registrations"`
}

Registration payloads for client/registerCapability (server → client).

type ResponseError

type ResponseError struct {
	Code    int             `json:"code"`
	Message string          `json:"message"`
	Data    json.RawMessage `json:"data,omitempty"`
}

ResponseError is a JSON-RPC error object.

func (*ResponseError) Error

func (e *ResponseError) Error() string

type SaveOptions

type SaveOptions struct {
	IncludeText bool `json:"includeText"`
}

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the Rune language server: a JSON-RPC/LSP 3.17 server over a framed connection. It holds open documents in an overlay and drives the shared analysis service. It executes nothing (spec FR-028).

func NewServer

func NewServer(r io.Reader, w io.Writer, opts Options) *Server

NewServer builds a server over r/w (stdin/stdout for a real client).

func (*Server) Run

func (s *Server) Run() error

Run serves the connection until exit or EOF. It returns nil on a clean shutdown+exit and an error if the stream fails unexpectedly.

type ServerCapabilities

type ServerCapabilities struct {
	TextDocumentSync   *TextDocumentSyncOptions `json:"textDocumentSync,omitempty"`
	CompletionProvider *CompletionOptions       `json:"completionProvider,omitempty"`
	DefinitionProvider bool                     `json:"definitionProvider,omitempty"`
	HoverProvider      bool                     `json:"hoverProvider,omitempty"`
	DocumentSymbol     bool                     `json:"documentSymbolProvider,omitempty"`
	DocumentFormatting bool                     `json:"documentFormattingProvider,omitempty"`
}

ServerCapabilities advertises only implemented features. Provider fields are pointers/omitempty so unimplemented capabilities are simply absent.

type ServerInfo

type ServerInfo struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

type TextDocumentContentChangeEvent

type TextDocumentContentChangeEvent struct {
	Range *Range `json:"range,omitempty"`
	Text  string `json:"text"`
}

TextDocumentContentChangeEvent is either an incremental change (Range set) or a full replacement (Range nil).

type TextDocumentIdentifier

type TextDocumentIdentifier struct {
	URI string `json:"uri"`
}

type TextDocumentItem

type TextDocumentItem struct {
	URI     string `json:"uri"`
	Version int    `json:"version"`
	Text    string `json:"text"`
}

type TextDocumentPositionParams

type TextDocumentPositionParams struct {
	TextDocument TextDocumentIdentifier `json:"textDocument"`
	Position     Position               `json:"position"`
}

TextDocumentPositionParams is the request shape for definition and hover.

type TextDocumentSyncOptions

type TextDocumentSyncOptions struct {
	OpenClose bool         `json:"openClose"`
	Change    int          `json:"change"` // 0 none, 1 full, 2 incremental
	Save      *SaveOptions `json:"save,omitempty"`
}

type TextEdit

type TextEdit struct {
	Range   Range  `json:"range"`
	NewText string `json:"newText"`
}

TextEdit replaces Range with NewText.

type VersionedTextDocumentIdentifier

type VersionedTextDocumentIdentifier struct {
	URI     string `json:"uri"`
	Version int    `json:"version"`
}

type WorkspaceFolder

type WorkspaceFolder struct {
	URI  string `json:"uri"`
	Name string `json:"name"`
}

Jump to

Keyboard shortcuts

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