Minga.Buffer.Lines (Minga v0.1.0)

Copy Markdown View Source

Presents document content as editor lines.

This module owns line-oriented questions: fetching visible line text, taking line ranges, maintaining the cached line index, and measuring how inserted text changes the current line.

Line index representation

The line index (line_offsets on Document) has three states:

  • Clean tuple {0, 6, 12, ...}: accurate line-start byte offsets.
  • Pending delta {:pending, starts, adjust_after, delta}: the tuple starts is stale; lines after adjust_after are shifted by delta. Queries apply the delta on the fly in O(1).
  • nil: needs a full rebuild from content.

Single-character inserts and deletes (the hot path) produce pending deltas in O(1). Newline insertion/deletion flushes the delta and splices entries, which is O(line_count) but rare relative to non-newline edits.

Summary

Functions

Returns how many line breaks appear in text.

Builds a line-start index from a complete text.

Returns how many editor lines text occupies.

Returns the content of one editor line without its trailing newline.

Applies the pending delta to produce a clean tuple.

Returns the cursor column at the end of the final line in text.

Returns up to count editor lines starting at first_line.

Returns indexed document text so callers can answer multiple line questions without rebuilding the line index.

Returns the content span for one editor line.

Returns where one editor line starts in the document text.

Updates line_offsets after deleting one character at the cursor (forward delete).

Updates line_offsets after deleting one character before the cursor.

Updates line_offsets after inserting text at the cursor. O(1) when text has no newlines.

Types

line_count()

@type line_count() :: pos_integer()

line_index()

@type line_index() :: non_neg_integer()

line_span()

@type line_span() :: {start :: non_neg_integer(), length :: non_neg_integer()}

line_starts()

@type line_starts() :: tuple()

snapshot()

@type snapshot() :: {line_starts(), String.t()}

Functions

break_count(text)

@spec break_count(String.t()) :: non_neg_integer()

Returns how many line breaks appear in text.

build_index(text)

@spec build_index(String.t()) :: line_starts()

Builds a line-start index from a complete text.

count(text)

@spec count(String.t()) :: line_count()

Returns how many editor lines text occupies.

fetch(doc, line)

@spec fetch(Minga.Buffer.Document.t(), line_index()) :: String.t() | nil

Returns the content of one editor line without its trailing newline.

flush_to_tuple(starts, adjust_after, delta)

@spec flush_to_tuple(line_starts(), non_neg_integer(), integer()) :: line_starts()

Applies the pending delta to produce a clean tuple.

last_line_width(text)

@spec last_line_width(String.t()) :: non_neg_integer()

Returns the cursor column at the end of the final line in text.

slice(doc, first_line, count)

Returns up to count editor lines starting at first_line.

snapshot(doc)

@spec snapshot(Minga.Buffer.Document.t()) :: snapshot()

Returns indexed document text so callers can answer multiple line questions without rebuilding the line index.

span(line_starts, line, text_size)

@spec span(line_starts(), line_index(), non_neg_integer()) :: line_span() | nil

Returns the content span for one editor line.

start(line_starts, line)

@spec start(line_starts(), line_index()) :: non_neg_integer()

Returns where one editor line starts in the document text.

update_after_delete_at(ls, cursor_line, char_size, newline?)

Updates line_offsets after deleting one character at the cursor (forward delete).

update_after_delete_before(ls, cursor_line, char_size, newline?)

Updates line_offsets after deleting one character before the cursor.

update_after_insert(ls, cursor_line, gap, text)

Updates line_offsets after inserting text at the cursor. O(1) when text has no newlines.