Skip to main content

TextBuffer

Struct TextBuffer 

Source
pub struct TextBuffer { /* private fields */ }
Expand description

A Ropey-backed text buffer.

Invariants and conventions:

  • The backing store is a ropey::Rope.
  • Public APIs should generally speak in char indices (Unicode scalar value offsets) and logical positions (line/col in chars) because Ropey’s safe indexing APIs are char-based.
  • Byte indexing can be supported where needed, but should not be the primary index type for the editor core.

Higher-level editor state (modes, undo, viewports, etc.) should be built on top of this type rather than embedded inside it.

Implementations§

Source§

impl TextBuffer

Source

pub fn new() -> Self

Create an empty buffer

Source

pub fn from_str(s: &str) -> Self

Create a buffer from UTF-8 text

Source

pub fn from_file(path: impl AsRef<Path>) -> Result<Self>

Load a file as UTF-8 and create a buffer.

This uses ropey’s streaming reader path and requires valid UTF-8.

Source

pub fn rope(&self) -> &Rope

Access the underlying rope.

Prefer higher-level APIs in other modules for most editor operations.

Source

pub fn rope_mut(&mut self) -> &mut Rope

Mutable access to the underlying rope (use this sparingly!)

Prefer dedicated editing APIs so invariants and bookkeeping remain easy to maintain.

Source

pub fn len_chars(&self) -> usize

Total number of chars in the buffer.

Kept here because it is a fundamental primitive used by most other modules.

Source

pub fn is_empty(&self) -> bool

Whether or not the buffer contains zero characters (is empty).

Source§

impl TextBuffer

Source

pub fn insert(&mut self, pos: Pos, text: &str) -> Pos

Insert text at the given logical position.

Returns the new cursor position (at the end of inserted text).

This is a primitive operation for higher-level editing commands.

Source

pub fn delete_range(&mut self, a: Pos, b: Pos) -> Pos

Delete a range between two positions (order-independent).

Returns the resulting cursor position (at the start of deletion).

Source

pub fn delete_selection(&mut self, sel: Selection) -> (Pos, bool)

Delete the selection (if any). Returns (new_cursor, did_delete).

Source

pub fn backspace(&mut self, sel: Selection) -> Selection

Backspace behavior:

  • if the selection is non-empty, delete it
  • otherwise delete the char before the cursor (if any)

Returns an empty selection at the updated cursor.

Source

pub fn delete(&mut self, sel: Selection) -> Selection

Delete (forward) behavior:

  • if the selection is non-empty, delete it
  • otherwise delete the char at the cursor (if any)

Returns an empty selection at the updated cursor.

Source

pub fn insert_newline(&mut self, sel: Selection) -> Selection

Insert a newline at the cursor (or replace the selection).

Returns an empty selection at the updated cursor.

Source

pub fn replace_line_indent( &mut self, line: usize, indent: &str, ) -> Option<(usize, usize)>

Replace the leading whitespace on line.

Returns (removed_chars, added_chars) when the line changed.

Source

pub fn trim_trailing_whitespace(&mut self) -> bool

Remove trailing spaces and tabs from every line in the buffer.

Returns true when at least one line was changed.

Source

pub fn apply_edit(&mut self, edit: Edit) -> Pos

Apply an Edit expressed in char indices.

Returns the resulting cursor position (end of inserted text, or start of deletion).

Source

pub fn apply_edits(&mut self, edits: &[Edit]) -> EditBatchSummary

Apply multiple edits sequentially and return a transaction-style summary.

Edits are applied in input order against the current buffer state.

Source

pub fn replace_selection(&mut self, sel: Selection, text: &str) -> Selection

Replace the current selection with text (if selection is empty, behaves like insert). This is a convenience method that a bunch of editor actions can use.

Returns an empty selection at the updated cursor.

Source

pub fn paste_before(&mut self, cursor: Pos, text: &str, linewise: bool) -> Pos

Paste text before the given cursor.

When linewise is true, insertion happens at the start of the current line and the returned cursor stays at that insertion point. When linewise is false, insertion happens at the cursor and the returned cursor is at the end of inserted text.

Source

pub fn paste_after(&mut self, cursor: Pos, text: &str, linewise: bool) -> Pos

Paste text after the given cursor.

When linewise is true, insertion happens at the beginning of the next logical line (clamped at the buffer boundary), and the returned cursor stays at the insertion point. When linewise is false, insertion happens after the cursor char on the current line (or at line end when already at EOL), and the returned cursor is at the end of inserted text.

Source

pub fn move_line_range_up_once( &mut self, start_line: usize, end_line_inclusive: usize, ) -> Option<(usize, usize)>

Move a contiguous line range up by one line.

Returns the moved range after the operation, or None when movement is not possible (for example when the range already starts at line 0).

Source

pub fn move_line_range_up( &mut self, start_line: usize, end_line_inclusive: usize, count: usize, ) -> Option<(usize, usize)>

Move a contiguous line range up by up to count lines.

Returns the moved range after all possible steps, or None when the range cannot be moved up at all.

Source

pub fn move_line_range_down_once( &mut self, start_line: usize, end_line_inclusive: usize, ) -> Option<(usize, usize)>

Move a contiguous line range down by one line.

Returns the moved range after the operation, or None when movement is not possible (for example when the range already ends at the final line).

Source

pub fn move_line_range_down( &mut self, start_line: usize, end_line_inclusive: usize, count: usize, ) -> Option<(usize, usize)>

Move a contiguous line range down by up to count lines.

Returns the moved range after all possible steps, or None when the range cannot be moved down at all.

Source

pub fn indent_line_span( &mut self, start_line: usize, end_line_inclusive: usize, count: usize, ) -> Vec<(usize, usize)>

Indent each line in a contiguous span by count tab characters.

Returns (line, chars_added) for every touched line.

Source

pub fn outdent_line_span( &mut self, start_line: usize, end_line_inclusive: usize, count: usize, ) -> Vec<(usize, usize)>

Outdent each line in a contiguous span by up to count levels.

One outdent level removes either one leading tab or up to four leading spaces. Returns (line, chars_removed) for every touched line.

Source§

impl TextBuffer

Source

pub fn len_lines(&self) -> usize

Number of lines in the buffer.

Ropey counts lines by '\n' boundaries and always reports at least 1 line, even for empty text.

Source

pub fn clamp_line(&self, line: usize) -> usize

Clamp a line index to the valid range [0, len_lines - 1].

If the buffer is empty, Ropey still reports len_lines() == 1, so this always returns a valid line index.

Source

pub fn line_to_char(&self, line: usize) -> usize

Returns the absolute char index at the start of line.

line is clamped into a valid range.

Source

pub fn char_to_line(&self, char_idx: usize) -> usize

Returns the line index containing char_idx.

char_idx is clamped to [0, len_chars].

Source

pub fn line_len_chars(&self, line: usize) -> usize

Returns the length of line in chars, excluding a trailing '\n' if present.

This corresponds to the number of valid “columns” for a (line, col) cursor model where the newline is not considered part of the line.

Source

pub fn line_first_non_whitespace_col(&self, line: usize) -> usize

Returns the first non-whitespace column on line.

If the line is all whitespace or empty, this returns line_len_chars(line).

Source

pub fn line_string(&self, line: usize) -> String

Returns the line content as a String, excluding a trailing '\n' if present.

Source

pub fn line_slice(&self, line: usize) -> RopeSlice<'_>

Returns a non-allocating line slice excluding a trailing '\n' if present.

Source

pub fn line_char_range(&self, line: usize) -> Range<usize>

Returns the char range [start, end) for the line content, excluding a trailing '\n'.

This will be useful for operations like “delete to end of line” or yanking the line content without the newline.

Source

pub fn line_full_end_char(&self, line: usize) -> usize

Returns the absolute char index of the end of line, including a trailing '\n' when one exists.

This is useful for line-block transforms that need stable slice boundaries across both newline-terminated and non-terminated final lines.

Source§

impl TextBuffer

Source

pub fn clamp_pos(&self, pos: Pos) -> Pos

Clamp a position to a valid location in the buffer.

  • Line is clamped to [0, len_lines - 1]
  • Column is clamped to [0, line_len_chars(line)]
Source

pub fn pos_to_char(&self, pos: Pos) -> usize

Convert Pos (line+col) to absolute char index in the rope.

The position is clamped first.

Source

pub fn char_to_pos(&self, char_idx: usize) -> Pos

Convert absolute char index to Pos (line+col).

char_idx is clamped to [0, len_chars].

Source

pub fn move_left(&self, pos: Pos) -> Pos

Move position left by one char, staying within buffer.

Source

pub fn move_right(&self, pos: Pos) -> Pos

Move position right by one char, staying within buffer.

Source

pub fn move_up(&self, pos: Pos) -> Pos

Move up one line, preserving column as much as possible.

This implementation does not track a preferred column.

Source

pub fn move_down(&self, pos: Pos) -> Pos

Move down one line, preserving column as much as possible.

This implementation does not track a preferred column.

Source

pub fn char_at(&self, pos: Pos) -> Option<char>

Get the char at a position, if it’s within the line’s content (not including newline).

Source

pub fn char_before(&self, pos: Pos) -> Option<char>

Get the char before a position, if one exists.

Source§

impl TextBuffer

Source

pub fn find_char_after_on_line(&self, pos: Pos, needle: char) -> Option<Pos>

Find the next occurrence of needle after pos on the same line.

Source

pub fn find_char_before_on_line(&self, pos: Pos, needle: char) -> Option<Pos>

Find the previous occurrence of needle before pos on the same line.

Source

pub fn matching_delimiter(&self, pos: Pos) -> Option<Pos>

Find the delimiter paired with the delimiter under pos.

Source

pub fn find_matches(&self, needle: &str) -> Vec<(Pos, Pos)>

Find all non-overlapping literal matches of needle in the buffer.

Returned ranges are half-open (start, end) position pairs.

Source§

impl TextBuffer

Source

pub fn line_span_char_range( &self, start_line: usize, end_line_inclusive: usize, ) -> Range<usize>

Return a char range spanning full lines from start_line..=end_line_inclusive.

The end of the range includes a trailing newline when one exists.

Source

pub fn line_span_pos_range( &self, start_line: usize, end_line_inclusive: usize, ) -> (Pos, Pos)

Return a position range spanning full lines from start_line..=end_line_inclusive.

Source

pub fn line_span_text( &self, start_line: usize, end_line_inclusive: usize, ) -> String

Return text spanning full lines from start_line..=end_line_inclusive.

This preserves the underlying buffer content exactly.

Source

pub fn line_span_text_linewise_register( &self, start_line: usize, end_line_inclusive: usize, ) -> String

Return line-span text suitable for a line-wise register.

Ensures the returned text ends with '\n'.

Source

pub fn visual_charwise_pos_range(&self, selection: Selection) -> (Pos, Pos)

Return the charwise visual selection as an order-normalized deletion range.

Visual charwise mode is inclusive of the cursor endpoint.

Source

pub fn visual_linewise_pos_range(&self, selection: Selection) -> (Pos, Pos)

Return the linewise visual selection as a full-line deletion range.

Source

pub fn visual_charwise_text(&self, selection: Selection) -> String

Return visual charwise selection text (inclusive endpoint semantics).

Source

pub fn visual_linewise_text(&self, selection: Selection) -> String

Return visual linewise selection text for line-wise register semantics.

Source

pub fn visual_blockwise_pos_ranges( &self, selection: Selection, ) -> Vec<(Pos, Pos)>

Return visual block selection text/deletion slices without line collapsing.

Source

pub fn visual_blockwise_delete_ranges( &self, selection: Selection, ) -> Vec<(Pos, Pos)>

Return deletion ranges for visual block mode.

When the block fully covers a line’s content, delete the whole logical line so trailing text is pulled upward instead of leaving empty rows.

Source

pub fn visual_blockwise_text(&self, selection: Selection) -> String

Return visual selection text for the current visual mode.

Source

pub fn visual_selection_pos_ranges( &self, selection: Selection, mode: VisualModeKind, ) -> Vec<(Pos, Pos)>

Return visual selection deletion bounds for the current visual mode.

Source

pub fn visual_selection_text( &self, selection: Selection, mode: VisualModeKind, ) -> String

Return visual selection text for the current visual mode.

Source

pub fn visual_selection_edit_plan( &self, selection: Selection, mode: VisualModeKind, ) -> VisualSelectionEditPlan

Build a mode-aware visual selection edit plan.

Source

pub fn visual_selection_char_range_on_line( &self, selection: Selection, mode: VisualModeKind, line_idx: usize, ) -> Option<Range<usize>>

Return selection char bounds for a specific line_idx.

The returned range is half-open (start..end) in char-column units for that line and follows visual-mode inclusive endpoint behaviour.

Source§

impl TextBuffer

Source

pub fn slice_chars_ref(&self, start: usize, end: usize) -> RopeSlice<'_>

Get a non-allocating slice for a character range [start, end).

  • Indices are clamped to the buffer bounds.
  • If start > end, the values are swapped.
Source

pub fn slice_selection_ref(&self, sel: Selection) -> RopeSlice<'_>

Get a non-allocating slice for a selection (ordered).

Source

pub fn slice_pos_range_ref(&self, a: Pos, b: Pos) -> RopeSlice<'_>

Convenience: non-allocating slice by two logical positions (order-independent).

Source

pub fn to_string(&self) -> String

Get the full buffer as a String.

For large buffers, this allocates. Kept as an inherent method so call sites can use b.to_string() without depending on Display/ToString.

Source

pub fn slice_chars(&self, start: usize, end: usize) -> String

Get a String for a character range [start, end).

  • Indices are clamped to the buffer bounds.
  • If start > end, the values are swapped.

This is a convenience API; it allocates.

Source

pub fn slice_selection(&self, sel: Selection) -> String

Get the selected text for a selection (ordered).

This is a convenience API; it allocates.

Source

pub fn slice_pos_range(&self, a: Pos, b: Pos) -> String

Convenience: slice by two logical positions (order-independent).

This is useful when there are two cursors/marks and the substring between them without explicitly building a Selection.

Source§

impl TextBuffer

Source§

impl TextBuffer

Source

pub fn word_start_before(&self, pos: Pos) -> Pos

Find the start of the previous/current word-like run (b-style).

Source

pub fn word_end_after(&self, pos: Pos) -> Pos

Find the end of the current/next word-like run (e-style).

Source

pub fn word_start_after(&self, pos: Pos) -> Pos

Find the start of the next word-like run (w-style).

Trait Implementations§

Source§

impl Clone for TextBuffer

Source§

fn clone(&self) -> TextBuffer

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TextBuffer

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for TextBuffer

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.