lsp

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Feb 19, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package lsp provides a Language Server Protocol (LSP) implementation for markata-go.

Overview

The LSP server enables IDE features for markdown files with wikilink support:

  • Autocomplete: Type [[ to get suggestions for post slugs
  • Diagnostics: Warnings for broken [[wikilinks]] that don't resolve to a post
  • Hover: Show post title and description when hovering over a wikilink
  • Go to Definition: Navigate to the target post file (Ctrl+click)

Server

The Server type is the main LSP server implementation. It communicates over stdin/stdout using the Language Server Protocol (JSON-RPC 2.0).

Example usage:

srv := lsp.New(logger)
srv.Run(ctx, os.Stdin, os.Stdout)

Index

The Index type maintains an in-memory index of all markdown posts in the workspace. It tracks:

  • Post slugs and file paths
  • Titles and descriptions
  • Wikilinks contained in each file

The index is built when the server initializes and updated incrementally as files change.

Protocol Support

The server implements the following LSP methods:

Lifecycle:

  • initialize
  • initialized
  • shutdown
  • exit

Document Synchronization:

  • textDocument/didOpen
  • textDocument/didChange
  • textDocument/didClose
  • textDocument/didSave
  • workspace/didChangeWatchedFiles

Language Features:

  • textDocument/completion
  • textDocument/hover
  • textDocument/definition
  • textDocument/publishDiagnostics (server->client notification)

Editor Integration

For VS Code, create an extension that starts "markata-go lsp".

For Neovim with nvim-lspconfig:

require('lspconfig').markata.setup{
  cmd = { "markata-go", "lsp" },
  filetypes = { "markdown" },
}

For other editors, configure the LSP client to run "markata-go lsp" for markdown files.

Package server provides the Language Server Protocol implementation for markata-go.

Overview

The LSP server provides IDE features for markdown files with wikilink support:

  • Autocomplete for [[wikilinks]] (textDocument/completion)
  • Diagnostics for broken wikilinks (textDocument/publishDiagnostics)
  • Hover information showing post title and description (textDocument/hover)
  • Go to definition for navigating to linked posts (textDocument/definition)

Architecture

The server maintains an index of all markdown posts in the workspace, including:

  • File paths and slugs
  • Titles and descriptions
  • Wikilinks contained in each file

The index is built on initialization and updated incrementally as files change.

Index

Constants

View Source
const (
	CompletionItemKindText          = 1
	CompletionItemKindMethod        = 2
	CompletionItemKindFunction      = 3
	CompletionItemKindConstructor   = 4
	CompletionItemKindField         = 5
	CompletionItemKindVariable      = 6
	CompletionItemKindClass         = 7
	CompletionItemKindInterface     = 8
	CompletionItemKindModule        = 9
	CompletionItemKindProperty      = 10
	CompletionItemKindUnit          = 11
	CompletionItemKindValue         = 12
	CompletionItemKindEnum          = 13
	CompletionItemKindKeyword       = 14
	CompletionItemKindSnippet       = 15
	CompletionItemKindColor         = 16
	CompletionItemKindFile          = 17
	CompletionItemKindReference     = 18
	CompletionItemKindFolder        = 19
	CompletionItemKindEnumMember    = 20
	CompletionItemKindConstant      = 21
	CompletionItemKindStruct        = 22
	CompletionItemKindEvent         = 23
	CompletionItemKindOperator      = 24
	CompletionItemKindTypeParameter = 25
)

CompletionItemKind defines types of completion items.

View Source
const (
	InsertTextFormatPlainText = 1
	InsertTextFormatSnippet   = 2
)

InsertTextFormat constants.

View Source
const (
	MatchTypeSlug  = "slug"
	MatchTypeAlias = "alias"
	MatchTypeTitle = "title"
)

Match type constants for PostSearchResult.

View Source
const (
	// JSON-RPC errors
	ParseError     = -32700
	InvalidRequest = -32600
	MethodNotFound = -32601
	InvalidParams  = -32602
	InternalError  = -32603

	// LSP errors
	ServerNotInitialized = -32002
	RequestCancelled     = -32800
)

LSP error codes

View Source
const (
	DiagnosticSeverityError       = 1
	DiagnosticSeverityWarning     = 2
	DiagnosticSeverityInformation = 3
	DiagnosticSeverityHint        = 4
)

DiagnosticSeverity constants.

View Source
const (
	TextDocumentSyncKindNone        = 0
	TextDocumentSyncKindFull        = 1
	TextDocumentSyncKindIncremental = 2
)

TextDocumentSyncKind constants.

View Source
const (
	FileChangeTypeCreated = 1
	FileChangeTypeChanged = 2
	FileChangeTypeDeleted = 3
)

FileChangeType constants.

Variables

This section is empty.

Functions

This section is empty.

Types

type AdmonitionContext

type AdmonitionContext struct {
	// Marker is the admonition marker (!!!, ???, ???+)
	Marker string

	// TypePrefix is the partial type that has been typed (may be empty)
	TypePrefix string

	// MarkerStart is the column where the marker starts
	MarkerStart int

	// TypeStart is the column where the type starts (after marker + space)
	TypeStart int
}

AdmonitionContext contains information about the admonition context at a position.

type AdmonitionType

type AdmonitionType struct {
	// Name is the admonition type name (e.g., "note", "warning")
	Name string

	// Description provides a brief explanation of when to use this type
	Description string

	// Color is the primary color associated with this type (CSS color name or hex)
	Color string

	// Icon is an optional icon identifier for this type
	Icon string
}

AdmonitionType represents a built-in admonition type with metadata.

func AllAdmonitionTypes

func AllAdmonitionTypes() []AdmonitionType

AllAdmonitionTypes returns all built-in admonition types.

func GetAdmonitionType

func GetAdmonitionType(name string) *AdmonitionType

GetAdmonitionType returns the admonition type by name, or nil if not found.

type ClientCapabilities

type ClientCapabilities struct {
	TextDocument TextDocumentClientCapabilities `json:"textDocument,omitempty"`
	Workspace    WorkspaceClientCapabilities    `json:"workspace,omitempty"`
}

ClientCapabilities represents the client's capabilities.

type CodeDesc

type CodeDesc struct {
	Href string `json:"href"`
}

CodeDesc provides additional information about a diagnostic code.

type CompletionClientCapabilities

type CompletionClientCapabilities struct {
	DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
}

CompletionClientCapabilities represents completion client capabilities.

type CompletionContext

type CompletionContext struct {
	TriggerKind      int     `json:"triggerKind"`
	TriggerCharacter *string `json:"triggerCharacter,omitempty"`
}

CompletionContext contains additional information about the context.

type CompletionItem

type CompletionItem struct {
	Label            string         `json:"label"`
	Kind             int            `json:"kind,omitempty"`
	Detail           string         `json:"detail,omitempty"`
	Documentation    *MarkupContent `json:"documentation,omitempty"`
	InsertText       string         `json:"insertText,omitempty"`
	InsertTextFormat int            `json:"insertTextFormat,omitempty"`
	TextEdit         *TextEdit      `json:"textEdit,omitempty"`
	FilterText       string         `json:"filterText,omitempty"`
	SortText         string         `json:"sortText,omitempty"`
	Data             interface{}    `json:"data,omitempty"`
	AdditionalEdits  []TextEdit     `json:"additionalTextEdits,omitempty"`
	CommitCharacters []string       `json:"commitCharacters,omitempty"`
}

CompletionItem represents a completion suggestion.

type CompletionList

type CompletionList struct {
	IsIncomplete bool             `json:"isIncomplete"`
	Items        []CompletionItem `json:"items"`
}

CompletionList represents a collection of completion items.

type CompletionOptions

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

CompletionOptions represents completion options.

type CompletionParams

type CompletionParams struct {
	TextDocument TextDocumentIdentifier `json:"textDocument"`
	Position     Position               `json:"position"`
	Context      *CompletionContext     `json:"context,omitempty"`
}

CompletionParams contains the parameters for textDocument/completion.

type DefinitionParams

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

DefinitionParams contains the parameters for textDocument/definition.

type DiagRelated

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

DiagRelated represents related diagnostic information.

type Diagnostic

type Diagnostic struct {
	Range              Range         `json:"range"`
	Severity           int           `json:"severity,omitempty"`
	Code               interface{}   `json:"code,omitempty"`
	CodeDescription    *CodeDesc     `json:"codeDescription,omitempty"`
	Source             string        `json:"source,omitempty"`
	Message            string        `json:"message"`
	Tags               []int         `json:"tags,omitempty"`
	RelatedInformation []DiagRelated `json:"relatedInformation,omitempty"`
	Data               interface{}   `json:"data,omitempty"`
}

Diagnostic represents a diagnostic message.

type DidChangeTextDocumentParams

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

DidChangeTextDocumentParams contains the parameters for textDocument/didChange.

type DidChangeWatchedFilesClientCapabilities

type DidChangeWatchedFilesClientCapabilities struct {
	DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
}

DidChangeWatchedFilesClientCapabilities represents file watching capabilities.

type DidChangeWatchedFilesParams

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

DidChangeWatchedFilesParams contains the parameters for workspace/didChangeWatchedFiles.

type DidCloseTextDocumentParams

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

DidCloseTextDocumentParams contains the parameters for textDocument/didClose.

type DidOpenTextDocumentParams

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

DidOpenTextDocumentParams contains the parameters for textDocument/didOpen.

type DidSaveTextDocumentParams

type DidSaveTextDocumentParams struct {
	TextDocument TextDocumentIdentifier `json:"textDocument"`
	Text         *string                `json:"text,omitempty"`
}

DidSaveTextDocumentParams contains the parameters for textDocument/didSave.

type Document

type Document struct {
	URI     string
	Content string
	Version int
}

Document represents an open document in the editor.

type FileEvent

type FileEvent struct {
	URI  string `json:"uri"`
	Type int    `json:"type"` // 1=Created, 2=Changed, 3=Deleted
}

FileEvent represents a file event.

type FrontmatterContext

type FrontmatterContext struct {
	// InFrontmatter indicates if the cursor is within the frontmatter section
	InFrontmatter bool

	// IsFieldName indicates if the cursor is in a position for a field name
	IsFieldName bool

	// IsFieldValue indicates if the cursor is in a position for a field value
	IsFieldValue bool

	// CurrentField is the field name if we're editing a value
	CurrentField string

	// Prefix is the text before the cursor (for filtering)
	Prefix string

	// StartCol is the column where the prefix starts
	StartCol int

	// ExistingFields contains field names already present in the frontmatter
	ExistingFields map[string]bool
}

FrontmatterContext contains information about the cursor position within frontmatter.

type FrontmatterField

type FrontmatterField struct {
	// Name is the field name (e.g., "title", "date")
	Name string

	// Type is the field type for documentation (e.g., "string", "boolean", "date")
	Type string

	// Description is a human-readable description of the field
	Description string

	// Required indicates if the field is required
	Required bool

	// Values contains allowed values for enum-like fields (e.g., ["true", "false"])
	Values []string

	// DefaultValue is the default value if any
	DefaultValue string

	// Snippet is the completion snippet (uses $1, $2 for placeholders)
	Snippet string
}

FrontmatterField represents a frontmatter field definition for auto-completion.

type Hover

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

Hover represents hover information.

type HoverClientCapabilities

type HoverClientCapabilities struct {
	DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
}

HoverClientCapabilities represents hover client capabilities.

type HoverParams

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

HoverParams contains the parameters for textDocument/hover.

type Index

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

Index maintains an index of all markdown posts in the workspace.

func NewIndex

func NewIndex(logger *log.Logger) *Index

NewIndex creates a new post index.

func (*Index) AllMentions

func (idx *Index) AllMentions() []*MentionInfo

AllMentions returns all indexed mentions (unique by handle).

func (*Index) AllPosts

func (idx *Index) AllPosts() []*PostInfo

AllPosts returns all indexed posts (unique by slug, excluding alias entries).

func (*Index) Build

func (idx *Index) Build(rootPath string) error

Build indexes all markdown files in the workspace.

func (*Index) GetByHandle

func (idx *Index) GetByHandle(handle string) *MentionInfo

GetByHandle returns a mention by handle or alias (case-insensitive).

func (*Index) GetBySlug

func (idx *Index) GetBySlug(slug string) *PostInfo

GetBySlug returns post info for a slug.

func (*Index) GetByURI

func (idx *Index) GetByURI(uri string) *PostInfo

GetByURI returns post info for a URI.

func (*Index) Remove

func (idx *Index) Remove(uri string)

Remove removes a file from the index.

func (*Index) SearchMentions

func (idx *Index) SearchMentions(prefix string) []*MentionInfo

SearchMentions returns mentions matching a prefix.

func (*Index) SearchPosts

func (idx *Index) SearchPosts(prefix string) []*PostInfo

SearchPosts returns posts matching a prefix.

func (*Index) SearchPostsWithMatch

func (idx *Index) SearchPostsWithMatch(prefix string) []PostSearchResult

SearchPostsWithMatch returns posts matching a prefix with match information. Results are deduplicated - each post appears once with the best match type (slug matches take precedence over alias matches, which take precedence over title matches).

func (*Index) Update

func (idx *Index) Update(uri, content string) error

Update updates the index for a single file.

type InitializeParams

type InitializeParams struct {
	ProcessID        *int               `json:"processId"`
	RootURI          *string            `json:"rootUri"`
	RootPath         *string            `json:"rootPath"`
	Capabilities     ClientCapabilities `json:"capabilities"`
	Trace            string             `json:"trace,omitempty"`
	WorkspaceFolders []WorkspaceFolder  `json:"workspaceFolders,omitempty"`
}

InitializeParams contains the parameters for initialize.

type InitializeResult

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

InitializeResult is the result of the initialize request.

type Location

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

Location represents a location inside a resource.

type MarkupContent

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

MarkupContent represents content with optional markup.

type MentionInfo

type MentionInfo struct {
	// Handle is the primary handle (e.g., "daverupert")
	Handle string

	// Aliases are alternative handles that resolve to this mention
	Aliases []string

	// Title is the display name (e.g., "Dave Rupert")
	Title string

	// Description is a short description
	Description string

	// SiteURL is the website URL (external mentions only)
	SiteURL string

	// FeedURL is the RSS/Atom feed URL (external mentions only)
	FeedURL string

	// IsInternal indicates this mention comes from a post, not blogroll
	IsInternal bool

	// Slug is the post slug (internal mentions only)
	Slug string

	// Path is the file path (internal mentions only)
	Path string
}

MentionInfo contains indexed information about a mention. Mentions can be external (from blogroll) or internal (from posts matching a filter).

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 represents a JSON-RPC 2.0 message.

type Position

type Position struct {
	Line      int `json:"line"`      // 0-based line number
	Character int `json:"character"` // 0-based character offset
}

Position represents a position in a text document.

type PostInfo

type PostInfo struct {
	// URI is the file URI (file:///path/to/file.md)
	URI string

	// Path is the file system path
	Path string

	// Slug is the URL-safe identifier
	Slug string

	// Title is the post title (from frontmatter or filename)
	Title string

	// Description is the post description/excerpt
	Description string

	// Metadata is the parsed frontmatter for filter evaluation
	Metadata map[string]interface{}

	// Aliases are alternative slugs that resolve to this post
	Aliases []string

	// Wikilinks contains all wikilinks found in the post
	Wikilinks []WikilinkInfo
}

PostInfo contains indexed information about a post.

type PostSearchResult

type PostSearchResult struct {
	Post       *PostInfo
	MatchedBy  string // "slug", "alias", or "title"
	MatchedKey string // The actual slug/alias that matched
}

PostSearchResult contains a post and how it was matched.

type PublishDiagnosticsParams

type PublishDiagnosticsParams struct {
	URI         string       `json:"uri"`
	Version     *int         `json:"version,omitempty"`
	Diagnostics []Diagnostic `json:"diagnostics"`
}

PublishDiagnosticsParams contains the parameters for publishDiagnostics.

type Range

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

Range represents a range in a text document.

type ResponseError

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

ResponseError represents a JSON-RPC 2.0 error.

type SaveOptions

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

SaveOptions represents save options.

type Server

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

Server is the LSP server implementation for markata-go.

func New

func New(logger *log.Logger) *Server

New creates a new LSP server.

func (*Server) Run

func (s *Server) Run(ctx context.Context, reader io.Reader, writer io.Writer) error

Run starts the LSP server, reading from reader and writing to writer. The server uses JSON-RPC 2.0 over the LSP protocol.

type ServerCapabilities

type ServerCapabilities struct {
	TextDocumentSync   *TextDocumentSyncOptions `json:"textDocumentSync,omitempty"`
	CompletionProvider *CompletionOptions       `json:"completionProvider,omitempty"`
	HoverProvider      bool                     `json:"hoverProvider,omitempty"`
	DefinitionProvider bool                     `json:"definitionProvider,omitempty"`
	Workspace          *WorkspaceOptions        `json:"workspace,omitempty"`
}

ServerCapabilities represents the server's capabilities.

type ServerInfo

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

ServerInfo provides information about the server.

type TextDocumentClientCapabilities

type TextDocumentClientCapabilities struct {
	Completion CompletionClientCapabilities `json:"completion,omitempty"`
	Hover      HoverClientCapabilities      `json:"hover,omitempty"`
}

TextDocumentClientCapabilities represents text document client capabilities.

type TextDocumentContentChangeEvent

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

TextDocumentContentChangeEvent represents a text document content change event.

type TextDocumentIdentifier

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

TextDocumentIdentifier identifies a text document.

type TextDocumentItem

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

TextDocumentItem represents a text document item.

type TextDocumentSyncOptions

type TextDocumentSyncOptions struct {
	OpenClose bool         `json:"openClose,omitempty"`
	Change    int          `json:"change,omitempty"` // 0=None, 1=Full, 2=Incremental
	Save      *SaveOptions `json:"save,omitempty"`
}

TextDocumentSyncOptions represents text document sync options.

type TextEdit

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

TextEdit represents a text edit operation.

type VersionedTextDocumentIdentifier

type VersionedTextDocumentIdentifier struct {
	TextDocumentIdentifier
	Version int `json:"version"`
}

VersionedTextDocumentIdentifier identifies a specific version of a text document.

type WikilinkInfo

type WikilinkInfo struct {
	// Target is the slug being linked to
	Target string

	// DisplayText is the optional display text
	DisplayText string

	// Line is the 0-based line number
	Line int

	// StartChar is the 0-based character position of [[
	StartChar int

	// EndChar is the 0-based character position after ]]
	EndChar int
}

WikilinkInfo contains information about a wikilink in a post.

type WorkspaceClientCapabilities

type WorkspaceClientCapabilities struct {
	DidChangeWatchedFiles DidChangeWatchedFilesClientCapabilities `json:"didChangeWatchedFiles,omitempty"`
}

WorkspaceClientCapabilities represents workspace client capabilities.

type WorkspaceFolder

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

WorkspaceFolder represents a workspace folder.

type WorkspaceFoldersServerCapabilities

type WorkspaceFoldersServerCapabilities struct {
	Supported           bool `json:"supported,omitempty"`
	ChangeNotifications bool `json:"changeNotifications,omitempty"`
}

WorkspaceFoldersServerCapabilities represents workspace folder capabilities.

type WorkspaceOptions

type WorkspaceOptions struct {
	WorkspaceFolders *WorkspaceFoldersServerCapabilities `json:"workspaceFolders,omitempty"`
}

WorkspaceOptions represents workspace options.

Jump to

Keyboard shortcuts

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