Skip to content

refactor(md): Add indent to buffer events and list streaming#657

Merged
JeanMertz merged 4 commits into
mainfrom
prr225
May 19, 2026
Merged

refactor(md): Add indent to buffer events and list streaming#657
JeanMertz merged 4 commits into
mainfrom
prr225

Conversation

@JeanMertz
Copy link
Copy Markdown
Collaborator

The Event enum variants have been converted from tuple structs to named-field structs, each gaining an indent: usize field that carries the visual column at which the renderer should place the content. For example, Event::Block(String) becomes Event::Block { content: String, indent: usize }.

A new InList buffer state replaces the old ad-hoc list-streaming logic inside handle_buffering_paragraph. It tracks marker_column, content_column, ordering, delimiter, and item count, and pushes/pops a parent-state stack when entering nested containers (sub-lists or fenced code blocks inside list items). Each sibling marker triggers an immediate flush of the preceding item as a Block with the list's marker_column as its visual indent, so items stream individually rather than buffering the whole list.

The Buffer::flush() -> Option<String> API is replaced by flush_events() -> Vec<Event>, which correctly splits any queued items at sibling-marker boundaries, renumbers ordered-list markers relative to start_number + items_flushed, and emits the final partial segment as a Flush event with the right indent.

TerminalOptions gains an indent field, threaded through Formatter::format_terminal_with, TerminalWriter::new, and the chat renderer's print_block / print_code / terminal_options helpers. TerminalWriter seeds its initial prefix with indent spaces so every rendered line starts at the requested visual column. A new indent_lines helper in the chat renderer prepends the indent to raw code-block lines that have already been highlighted.

The practical effect: when an LLM streams a response with nested lists or fenced code blocks inside list items, each item and code line now renders at the correct visual column as it arrives, rather than being buffered until the whole list is received or rendered at column 0.

The `Event` enum variants have been converted from tuple structs to
named-field structs, each gaining an `indent: usize` field that carries
the visual column at which the renderer should place the content. For
example, `Event::Block(String)` becomes `Event::Block { content: String,
indent: usize }`.

A new `InList` buffer state replaces the old ad-hoc list-streaming logic
inside `handle_buffering_paragraph`. It tracks `marker_column`,
`content_column`, ordering, delimiter, and item count, and pushes/pops a
parent-state stack when entering nested containers (sub-lists or fenced
code blocks inside list items). Each sibling marker triggers an
immediate flush of the preceding item as a `Block` with the list's
`marker_column` as its visual indent, so items stream individually
rather than buffering the whole list.

The `Buffer::flush() -> Option<String>` API is replaced by
`flush_events() -> Vec<Event>`, which correctly splits any queued items
at sibling-marker boundaries, renumbers ordered-list markers relative to
`start_number + items_flushed`, and emits the final partial segment as a
`Flush` event with the right indent.

`TerminalOptions` gains an `indent` field, threaded through
`Formatter::format_terminal_with`, `TerminalWriter::new`, and the chat
renderer's `print_block` / `print_code` / `terminal_options` helpers.
`TerminalWriter` seeds its initial `prefix` with `indent` spaces so
every rendered line starts at the requested visual column. A new
`indent_lines` helper in the chat renderer prepends the indent to raw
code-block lines that have already been highlighted.

The practical effect: when an LLM streams a response with nested lists
or fenced code blocks inside list items, each item and code line now
renders at the correct visual column as it arrives, rather than being
buffered until the whole list is received or rendered at column 0.

Signed-off-by: Jean Mertz <git@jeanmertz.com>
JeanMertz added 3 commits May 18, 2026 23:51
Signed-off-by: Jean Mertz <git@jeanmertz.com>
Signed-off-by: Jean Mertz <git@jeanmertz.com>
Signed-off-by: Jean Mertz <git@jeanmertz.com>
@JeanMertz JeanMertz merged commit 667129c into main May 19, 2026
14 checks passed
@JeanMertz JeanMertz deleted the prr225 branch May 19, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant