Skip to main content

Buffer

Struct Buffer 

Source
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: Rect

The 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

Source

pub fn empty(area: Rect) -> Self

Create a buffer filled with blank cells covering area.

Source

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.

Source

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.

Source

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

Source

pub fn in_bounds(&self, x: u32, y: u32) -> bool

Returns true if (x, y) is within the buffer’s area.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn reset(&mut self)

Reset every cell to a blank space with default style, and clear the clip stack.

Source

pub fn reset_with_bg(&mut self, bg: Color)

Reset every cell and apply a background color to all cells.

Source

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.

Source

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"));

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.