MingaEditor.UI.Highlight (Minga v0.1.0)

Copy Markdown View Source

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.

t()

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

style_resolver()

@type style_resolver() :: (String.t() -> Minga.Core.Face.t())

Style resolver: a function that maps capture names to Face structs.

styled_segment()

@type styled_segment() :: {text :: String.t(), style :: Minga.Core.Face.t()}

A styled text segment for rendering.

t()

@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

byte_offset_for_line(lines, line_index)

@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.

from_theme(theme)

@spec from_theme(MingaEditor.UI.Theme.t()) :: t()

Creates an empty highlight state using the syntax map from a MingaEditor.UI.Theme.t() struct.

new()

@spec new() :: t()

Creates an empty highlight state with the default theme.

new(syntax)

@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.

put_names(hl, names)

@spec put_names(t(), [String.t()]) :: t()

Stores capture names from a highlight_names event.

put_spans(hl, version, spans)

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.

resolver_for(registry)

@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).

styles_for_line(hl, line_text, line_start_byte, resolver \\ nil)

@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).

styles_for_visible_lines(hl, lines, resolver \\ 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}.