pub struct Buffer {
pub area: Rect,
pub content: Vec<Cell>,
/* private fields */
}Expand description
A 2D grid of Cells backing the terminal display.
Two buffers are kept (current + previous); only the diff is flushed to the terminal, giving immediate-mode ergonomics with retained-mode efficiency.
The buffer also maintains a clip stack. Push a Rect with
Buffer::push_clip to restrict writes to that region, and pop it with
Buffer::pop_clip when done.
Fields§
§area: RectThe area this buffer covers, in terminal coordinates.
content: Vec<Cell>Flat row-major storage of all cells. Length equals area.width * area.height.
Implementations§
Source§impl Buffer
impl Buffer
Sourcepub fn raw_sequence(&mut self, x: u32, y: u32, seq: String)
pub fn raw_sequence(&mut self, x: u32, y: u32, seq: String)
Store a raw escape sequence to be written at position (x, y) during flush.
Used for Sixel images and other passthrough sequences. Respects the clip stack: sequences fully outside the current clip are skipped.
Sourcepub fn push_clip(&mut self, rect: Rect)
pub fn push_clip(&mut self, rect: Rect)
Push a clipping rectangle onto the clip stack.
Subsequent writes are restricted to the intersection of all active clip regions. Nested calls intersect with the current clip, so the effective clip can only shrink, never grow.
Sourcepub fn pop_clip(&mut self)
pub fn pop_clip(&mut self)
Pop the most recently pushed clipping rectangle.
After this call, writes are clipped to the previous region (or unclipped if the stack is now empty).
Sourcepub fn in_bounds(&self, x: u32, y: u32) -> bool
pub fn in_bounds(&self, x: u32, y: u32) -> bool
Returns true if (x, y) is within the buffer’s area.
Sourcepub fn get(&self, x: u32, y: u32) -> &Cell
pub fn get(&self, x: u32, y: u32) -> &Cell
Return a reference to the cell at (x, y).
Panics if (x, y) is out of bounds. Use Buffer::try_get when the
coordinates may come from untrusted input.
Sourcepub fn get_mut(&mut self, x: u32, y: u32) -> &mut Cell
pub fn get_mut(&mut self, x: u32, y: u32) -> &mut Cell
Return a mutable reference to the cell at (x, y).
Panics if (x, y) is out of bounds. Use Buffer::try_get_mut when
the coordinates may come from untrusted input.
Sourcepub fn try_get(&self, x: u32, y: u32) -> Option<&Cell>
pub fn try_get(&self, x: u32, y: u32) -> Option<&Cell>
Return a reference to the cell at (x, y), or None if out of bounds.
Non-panicking counterpart to Buffer::get. Prefer this inside
draw() closures when coordinates are computed from mouse input,
scroll offsets, or other sources that could land outside the buffer.
Sourcepub fn try_get_mut(&mut self, x: u32, y: u32) -> Option<&mut Cell>
pub fn try_get_mut(&mut self, x: u32, y: u32) -> Option<&mut Cell>
Return a mutable reference to the cell at (x, y), or None if out
of bounds.
Non-panicking counterpart to Buffer::get_mut.
Sourcepub fn set_string(&mut self, x: u32, y: u32, s: &str, style: Style)
pub fn set_string(&mut self, x: u32, y: u32, s: &str, style: Style)
Write a string into the buffer starting at (x, y).
Respects cell boundaries and Unicode character widths. Wide characters (e.g., CJK) occupy two columns; the trailing cell is blanked. Writes that fall outside the current clip region are skipped but still advance the cursor position.
Sourcepub fn set_string_linked(
&mut self,
x: u32,
y: u32,
s: &str,
style: Style,
url: &str,
)
pub fn set_string_linked( &mut self, x: u32, y: u32, s: &str, style: Style, url: &str, )
Write a hyperlinked string into the buffer starting at (x, y).
Like Buffer::set_string but attaches an OSC 8 hyperlink URL to each
cell. The terminal renders these cells as clickable links.
Sourcepub fn set_char(&mut self, x: u32, y: u32, ch: char, style: Style)
pub fn set_char(&mut self, x: u32, y: u32, ch: char, style: Style)
Write a single character at (x, y) with the given style.
No-ops if (x, y) is out of bounds or outside the current clip region.
Sourcepub fn diff<'a>(&'a self, other: &'a Buffer) -> Vec<(u32, u32, &'a Cell)>
pub fn diff<'a>(&'a self, other: &'a Buffer) -> Vec<(u32, u32, &'a Cell)>
Compute the diff between self (current) and other (previous).
Returns (x, y, cell) tuples for every cell that changed. Useful for
custom backends or tests that need to inspect changed cells directly.
§Allocation
Allocates a new Vec on every call. For high-frequency use
(per-frame diffing in a render loop), prefer the internal
flush_buffer_diff path used by crate::run, which streams updates
directly to the backend without an intermediate Vec. Calling
diff() on every frame in a 60 fps loop adds one heap allocation
(sized to the changed-cell count) per frame.
§Benchmarks
benches/benchmarks.rs exercises this path in bench_buffer_diff.
Sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Reset every cell to a blank space with default style, and clear the clip stack.
Sourcepub fn reset_with_bg(&mut self, bg: Color)
pub fn reset_with_bg(&mut self, bg: Color)
Reset every cell and apply a background color to all cells.
Sourcepub fn resize(&mut self, area: Rect)
pub fn resize(&mut self, area: Rect)
Resize the buffer to fit a new area, resetting all cells.
If the new area is larger, new cells are initialized to blank. All existing content is discarded.
Sourcepub fn snapshot_format(&self) -> String
pub fn snapshot_format(&self) -> String
Serialize the buffer into a stable, styled-snapshot format suitable for
snapshot testing (e.g. with insta::assert_snapshot!).
§Format
One line per buffer row, joined with \n. Within a row, runs of cells
that share an identical Style are grouped. The default style (no
foreground, no background, no modifiers) emits unannotated text —
no [...] markers. Any non-default run is wrapped:
[fg=...,bg=...,mods]"text"[/]Trailing whitespace per row is preserved in the styled segment but
trailing default-style spaces at the end of a row are emitted verbatim
(they are visually invisible in diffs). Empty cells render as a single
space. The terminating [/] marker only appears when a styled run is
in effect at the end of a row.
§Color formatting
Named palette colors use short lowercase codes:
reset, black, red, green, yellow, blue, magenta, cyan,
white, dark_gray, light_red, light_green, light_yellow,
light_blue, light_magenta, light_cyan, light_white. RGB colors
emit #rrggbb. Indexed palette colors emit idx<N> (decimal).
§Modifier formatting
Modifiers are emitted as comma-separated lowercase tokens in a fixed
canonical order: bold, dim, italic, underline, reversed,
strikethrough. Order is independent of the bit pattern, so two
equivalent Modifiers values always serialize identically.
§Stability
The output format is stable across patch and minor versions of SLT.
Names use a hand-rolled formatter (not Debug) so derives changing
upstream cannot accidentally break locked snapshots. A breaking change
to the format would be reserved for a major version bump.
§Determinism
Identical input buffers always produce byte-equal output. This is a hard requirement — snapshot tests rely on it.
§Example
use slt::{Buffer, Color, Rect, Style};
let mut buf = Buffer::empty(Rect::new(0, 0, 5, 1));
buf.set_string(0, 0, "ab", Style::new().fg(Color::Red).bold());
buf.set_string(2, 0, "cd", Style::new());
let snap = buf.snapshot_format();
assert!(snap.starts_with("[fg=red,bold]\"ab\"[/]cd"));