Stores and queries tree-sitter highlight state for a buffer.
Holds the current highlight spans (byte ranges + capture IDs),
capture names, version counter, and theme. Provides styles_for_line/3
to split a line into styled segments for rendering.
Summary
Types
Style resolver: a function that maps capture names to Face structs.
A styled text segment for rendering.
Highlight state for a buffer.
Functions
Computes the byte offset for a given line index within a list of lines.
Creates an empty highlight state using the syntax map from a MingaEditor.UI.Theme.t() struct.
Creates an empty highlight state with the default theme.
Creates an empty highlight state with a syntax theme map.
Stores capture names from a highlight_names event.
Stores highlight spans from a highlight_spans event.
Returns a style resolver function for the given face registry.
Splits a line into styled segments based on highlight spans.
Batch-compute styled segments for multiple consecutive lines in a single
pass over the span tuple. Returns a list of [styled_segment()] in the
same order as the input lines.
Types
@type style_resolver() :: (String.t() -> Minga.Core.Face.t())
Style resolver: a function that maps capture names to Face structs.
@type styled_segment() :: {text :: String.t(), style :: Minga.Core.Face.t()}
A styled text segment for rendering.
@type t() :: %MingaEditor.UI.Highlight{ capture_names: tuple(), face_registry: MingaEditor.UI.Face.Registry.t(), spans: tuple() | [map()], theme: MingaEditor.UI.Theme.syntax(), version: non_neg_integer() }
Highlight state for a buffer.
Functions
@spec byte_offset_for_line([String.t()], non_neg_integer()) :: non_neg_integer()
Computes the byte offset for a given line index within a list of lines.
Each line is separated by a newline (1 byte), so the offset is the
cumulative byte_size of all preceding lines plus their newlines.
@spec from_theme(MingaEditor.UI.Theme.t()) :: t()
Creates an empty highlight state using the syntax map from a MingaEditor.UI.Theme.t() struct.
@spec new() :: t()
Creates an empty highlight state with the default theme.
@spec new(MingaEditor.UI.Theme.syntax()) :: t()
Creates an empty highlight state with a syntax theme map.
Builds a Face.Registry from the syntax map so face inheritance
is always available.
Stores capture names from a highlight_names event.
@spec put_spans(t(), non_neg_integer(), [ MingaEditor.Frontend.Protocol.highlight_span() ]) :: t()
Stores highlight spans from a highlight_spans event.
Only updates if the incoming version is >= the current version, preventing stale async results from overwriting newer ones.
@spec resolver_for(MingaEditor.UI.Face.Registry.t()) :: style_resolver()
Returns a style resolver function for the given face registry.
Use this to pass to styles_for_line/4 when you want to override
the Highlight struct's built-in face registry (e.g., with buffer-local
face overrides applied).
@spec styles_for_line(t(), String.t(), non_neg_integer(), style_resolver() | nil) :: [ styled_segment() ]
Splits a line into styled segments based on highlight spans.
Given a line's text and its starting byte offset within the buffer,
finds all overlapping spans and produces [{text_segment, Face.t()}].
Unstyled regions get Face.new() as their style (anonymous face with
all fields nil).
@spec styles_for_visible_lines( t(), [{String.t(), non_neg_integer()}], style_resolver() | nil ) :: [ [styled_segment()] ]
Batch-compute styled segments for multiple consecutive lines in a single
pass over the span tuple. Returns a list of [styled_segment()] in the
same order as the input lines.
This is O(total_spans + total_overlapping_pairs) regardless of file size,
compared to O(spans × visible_lines) for repeated styles_for_line/3 calls.
Use this for rendering visible lines.
Each element in lines is {line_text, line_start_byte}.