pub struct Buffer { /* private fields */ }Expand description
In-memory text buffer + cursor + viewport + per-row span cache.
This is the core type the rest of sqeel-buffer builds on.
Phase 1 of the migration ships construction + getters only;
motion / edit / render APIs land in later phases. The
lines invariant — at least one entry, never empty — is
preserved by every later mutation.
Implementations§
Source§impl Buffer
impl Buffer
Sourcepub fn new() -> Self
pub fn new() -> Self
Construct an empty buffer with one empty row + cursor at
(0, 0). Caller publishes a viewport size on first draw.
Sourcepub fn from_str(text: &str) -> Self
pub fn from_str(text: &str) -> Self
Build a buffer from a flat string. Splits on \n; a trailing
\n produces a trailing empty line (matches every text
editor’s behaviour and keeps from_text(buf.as_string()) an
identity round-trip in the common case).
pub fn lines(&self) -> &[String]
pub fn line(&self, row: usize) -> Option<&str>
pub fn cursor(&self) -> Position
pub fn sticky_col(&self) -> Option<usize>
pub fn viewport(&self) -> Viewport
pub fn viewport_mut(&mut self) -> &mut Viewport
pub fn dirty_gen(&self) -> u64
Sourcepub fn set_cursor(&mut self, pos: Position)
pub fn set_cursor(&mut self, pos: Position)
Set cursor without scrolling. Caller is responsible for calling
Buffer::ensure_cursor_visible when they want viewport
follow. Clamps row and col to valid positions so motion
helpers don’t have to repeat the bound check.
Sourcepub fn set_sticky_col(&mut self, col: Option<usize>)
pub fn set_sticky_col(&mut self, col: Option<usize>)
Replace the sticky col (vim’s curswant). Motion code sets
this after vertical / horizontal moves; the buffer doesn’t
touch it on its own.
Sourcepub fn ensure_cursor_visible(&mut self)
pub fn ensure_cursor_visible(&mut self)
Bring the cursor into the visible viewport, scrolling by the
minimum amount needed. When viewport.wrap != Wrap::None and
viewport.text_width > 0, scrolling is screen-line aware:
top_row is advanced one visible doc row at a time until the
cursor’s screen row falls inside the viewport’s height.
Sourcepub fn cursor_screen_row(&self) -> Option<usize>
pub fn cursor_screen_row(&self) -> Option<usize>
Cursor’s screen row offset (0-based) from viewport.top_row
under the current wrap mode + text_width. None when wrap
is off, the cursor row is hidden by a fold, or the cursor sits
above top_row. Used by host-side scrolloff math.
Sourcepub fn screen_rows_between(&self, start: usize, end: usize) -> usize
pub fn screen_rows_between(&self, start: usize, end: usize) -> usize
Number of screen rows the doc range start..=end occupies
under the current wrap mode. Skips fold-hidden rows. Empty /
past-end ranges return 0. Wrap::None returns the visible
doc-row count (one screen row per doc row).
Sourcepub fn max_top_for_height(&self, height: usize) -> usize
pub fn max_top_for_height(&self, height: usize) -> usize
Earliest top_row such that screen_rows_between(top, last)
is at least height. Lets host-side scrolloff math clamp
top_row so the buffer never leaves blank rows below the
content. When the buffer’s total screen rows are smaller than
height this returns 0.
Sourcepub fn clamp_position(&self, pos: Position) -> Position
pub fn clamp_position(&self, pos: Position) -> Position
Clamp pos to the buffer’s content. Out-of-range row gets
pulled to the last row; out-of-range col gets pulled to the
row’s char count (one past last char — insertion point).
Sourcepub fn set_spans(&mut self, spans: Vec<Vec<Span>>)
pub fn set_spans(&mut self, spans: Vec<Vec<Span>>)
Replace the per-row syntax span overlay. Used by the host
once tree-sitter (or any other producer) has fresh styling
for the visible window. spans[row] corresponds to row
row; rows beyond spans.len() get no styling.
Sourcepub fn replace_all(&mut self, text: &str)
pub fn replace_all(&mut self, text: &str)
Replace the buffer’s full text in place. Cursor + sticky col are clamped to the new content; viewport stays put. Used during the migration off tui-textarea so the buffer can mirror the textarea’s content after every edit without rebuilding the whole struct.
pub fn marks(&self) -> &BTreeMap<char, Position>
pub fn spans(&self) -> &[Vec<Span>]
Sourcepub fn as_string(&self) -> String
pub fn as_string(&self) -> String
Concatenate the rows into a single String joined by \n.
Inverse of Buffer::from_str for content built without a
trailing newline.
Source§impl Buffer
impl Buffer
Sourcepub fn apply_edit(&mut self, edit: Edit) -> Edit
pub fn apply_edit(&mut self, edit: Edit) -> Edit
Apply edit and return the inverse. Pushing the inverse back
through Buffer::apply_edit restores the previous state.
Source§impl Buffer
impl Buffer
pub fn folds(&self) -> &[Fold]
Sourcepub fn add_fold(&mut self, start_row: usize, end_row: usize, closed: bool)
pub fn add_fold(&mut self, start_row: usize, end_row: usize, closed: bool)
Register a new fold. If an existing fold has the same
start_row, it’s replaced; otherwise the new one is inserted
in start-row order. Empty / inverted ranges are rejected.
Sourcepub fn remove_fold_at(&mut self, row: usize) -> bool
pub fn remove_fold_at(&mut self, row: usize) -> bool
Drop the fold whose range covers row. Returns true when a
fold was actually removed.
Sourcepub fn open_fold_at(&mut self, row: usize) -> bool
pub fn open_fold_at(&mut self, row: usize) -> bool
Open the fold at row (no-op if already open or no fold).
Sourcepub fn close_fold_at(&mut self, row: usize) -> bool
pub fn close_fold_at(&mut self, row: usize) -> bool
Close the fold at row (no-op if already closed or no fold).
Sourcepub fn toggle_fold_at(&mut self, row: usize) -> bool
pub fn toggle_fold_at(&mut self, row: usize) -> bool
Flip the closed/open state of the fold containing row.
Sourcepub fn open_all_folds(&mut self)
pub fn open_all_folds(&mut self)
zR — open every fold.
Sourcepub fn clear_all_folds(&mut self)
pub fn clear_all_folds(&mut self)
zE — eliminate every fold.
Sourcepub fn close_all_folds(&mut self)
pub fn close_all_folds(&mut self)
zM — close every fold.
Sourcepub fn fold_at_row(&self, row: usize) -> Option<&Fold>
pub fn fold_at_row(&self, row: usize) -> Option<&Fold>
First fold whose range contains row (most folds are
non-overlapping in vim’s model, so the first match is the
only match). Useful for the host’s za/zo/zc handlers.
True iff row is hidden by a closed fold (any fold).
Sourcepub fn next_visible_row(&self, row: usize) -> Option<usize>
pub fn next_visible_row(&self, row: usize) -> Option<usize>
First visible row strictly after row, skipping any rows hidden
by closed folds. Returns None past the end of the buffer.
Drives fold-aware j: closed folds count as a single visual line.
Sourcepub fn prev_visible_row(&self, row: usize) -> Option<usize>
pub fn prev_visible_row(&self, row: usize) -> Option<usize>
First visible row strictly before row, skipping hidden rows.
Returns None past the top of the buffer.
Sourcepub fn invalidate_folds_in_range(&mut self, start_row: usize, end_row: usize)
pub fn invalidate_folds_in_range(&mut self, start_row: usize, end_row: usize)
Drop every fold that touches [start_row, end_row]. Edit
paths call this to invalidate folds whose contents the user
just mutated — vim’s “edits inside a fold open it” behaviour.
Source§impl Buffer
impl Buffer
Sourcepub fn move_left(&mut self, count: usize)
pub fn move_left(&mut self, count: usize)
h — clamps at column 0; never wraps to the previous line.
Sourcepub fn move_right_in_line(&mut self, count: usize)
pub fn move_right_in_line(&mut self, count: usize)
l — clamps at the last char on the line. Operator
callers wanting “one past end” use Buffer::move_right_to_end.
Sourcepub fn move_right_to_end(&mut self, count: usize)
pub fn move_right_to_end(&mut self, count: usize)
Operator-context l: allowed past the last char so a range
motion includes it. Clamps at chars() (one past end).
Sourcepub fn move_line_start(&mut self)
pub fn move_line_start(&mut self)
0 — first column of the current row.
Sourcepub fn move_first_non_blank(&mut self)
pub fn move_first_non_blank(&mut self)
^ — first non-blank column. On a blank line it lands on 0.
Sourcepub fn move_line_end(&mut self)
pub fn move_line_end(&mut self)
$ — last char on the row. Empty rows stay at column 0.
Sourcepub fn move_last_non_blank(&mut self)
pub fn move_last_non_blank(&mut self)
g_ — last non-blank char on the row. Empty / all-blank rows
stay at column 0.
Sourcepub fn move_paragraph_prev(&mut self, count: usize)
pub fn move_paragraph_prev(&mut self, count: usize)
{ — previous blank line above the cursor, or row 0.
Sourcepub fn move_paragraph_next(&mut self, count: usize)
pub fn move_paragraph_next(&mut self, count: usize)
} — next blank line below the cursor, or last row.
Sourcepub fn move_up(&mut self, count: usize)
pub fn move_up(&mut self, count: usize)
k — count rows up; sticky col preserved across short rows.
Sourcepub fn move_down(&mut self, count: usize)
pub fn move_down(&mut self, count: usize)
j — count rows down; sticky col preserved across short rows.
Sourcepub fn move_screen_up(&mut self, count: usize)
pub fn move_screen_up(&mut self, count: usize)
gk — count visual rows up. With Wrap::None (or before
the host has published text_width), falls back to move_up
so existing tests + non-wrap callers behave unchanged. Under
wrap, walks one screen segment at a time, crossing into the
previous doc row only after exhausting the current row’s
segments.
Sourcepub fn move_screen_down(&mut self, count: usize)
pub fn move_screen_down(&mut self, count: usize)
gj — count visual rows down. See Buffer::move_screen_up.
Sourcepub fn move_bottom(&mut self, count: usize)
pub fn move_bottom(&mut self, count: usize)
G — last row (or count - 1 when count > 0), first non-blank.
count = 0 (the unprefixed form) jumps to the buffer’s bottom.
Sourcepub fn move_word_fwd(&mut self, big: bool, count: usize)
pub fn move_word_fwd(&mut self, big: bool, count: usize)
w / W — start of next word. big = true treats every
non-whitespace run as one word (vim’s WORD).
Sourcepub fn move_word_back(&mut self, big: bool, count: usize)
pub fn move_word_back(&mut self, big: bool, count: usize)
b / B — start of previous word.
Sourcepub fn match_bracket(&mut self) -> bool
pub fn match_bracket(&mut self) -> bool
% — jump to the matching bracket. Walks the buffer
counting nesting depth so nested pairs resolve correctly.
Returns true when the cursor moved.
Sourcepub fn find_char_on_line(&mut self, ch: char, forward: bool, till: bool) -> bool
pub fn find_char_on_line(&mut self, ch: char, forward: bool, till: bool) -> bool
f / F / t / T — find ch on the current row.
forward = true searches right of the cursor; till = true
stops one cell short of the match (the t/T semantic).
Returns true when the cursor moved.
Sourcepub fn move_word_end(&mut self, big: bool, count: usize)
pub fn move_word_end(&mut self, big: bool, count: usize)
e / E — end of current/next word.
Sourcepub fn move_viewport_top(&mut self, offset: usize)
pub fn move_viewport_top(&mut self, offset: usize)
H — top of the visible viewport plus offset rows
(0-based; vim uses 1-based count where bare H = 0). Lands
on the first non-blank of the resolved row.
Sourcepub fn move_viewport_middle(&mut self)
pub fn move_viewport_middle(&mut self)
M — middle row of the visible viewport.
Sourcepub fn move_viewport_bottom(&mut self, offset: usize)
pub fn move_viewport_bottom(&mut self, offset: usize)
L — bottom of the visible viewport, minus offset rows.
Sourcepub fn move_word_end_back(&mut self, big: bool, count: usize)
pub fn move_word_end_back(&mut self, big: bool, count: usize)
ge / gE — end of previous word. Walks backward until
the cursor sits on the last char of a word (the next char
is a different kind, or end-of-line).
Source§impl Buffer
impl Buffer
Sourcepub fn set_search_pattern(&mut self, re: Option<Regex>)
pub fn set_search_pattern(&mut self, re: Option<Regex>)
Set the active search pattern. Pass None to clear.
Subsequent Buffer::search_forward / search_backward
calls use the new pattern; n / N repeat the last set
pattern.
pub fn search_pattern(&self) -> Option<&Regex>
Sourcepub fn search_forward(&mut self, skip_current: bool) -> bool
pub fn search_forward(&mut self, skip_current: bool) -> bool
Move the cursor to the next match starting from (or just
after, when skip_current = true) the cursor. Wraps end-of-
buffer to row 0. Returns true when a match was found.
Sourcepub fn search_backward(&mut self, skip_current: bool) -> bool
pub fn search_backward(&mut self, skip_current: bool) -> bool
Move to the previous match. Symmetric with search_forward
but walks rows backwards and picks the rightmost match in
each row.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Buffer
impl RefUnwindSafe for Buffer
impl Send for Buffer
impl Sync for Buffer
impl Unpin for Buffer
impl UnsafeUnpin for Buffer
impl UnwindSafe for Buffer
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more