Skip to main content

redox_core/buffer/
edit.rs

1//! Edit types for applying changes to a `TextBuffer`.
2//!
3//! This module is intentionally small and self-contained so it can be reused by
4//! higher-level systems (undo/redo, macros, repeat, etc).
5//!
6//! All indices are **character indices** (Unicode scalar values), matching
7//! `ropey`'s primary indexing model.
8
9/// A text edit expressed in character indices within the buffer.
10///
11/// The `range` is half-open: `[start, end)`.
12/// - To represent an insertion, use an empty range: `start == end`.
13/// - To represent a deletion, use an empty `insert` string.
14/// - To represent a replacement, set both a non-empty range and insert text.
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub struct Edit {
17    pub range: core::ops::Range<usize>,
18    pub insert: String,
19}
20
21/// Summary returned by batched edit application.
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub struct EditBatchSummary {
24    /// Conservative changed character range after applying the batch.
25    pub changed_range: core::ops::Range<usize>,
26    /// Cursor position after the last applied edit.
27    pub cursor: crate::buffer::Pos,
28    /// Number of edits applied from the input slice.
29    pub edits_applied: usize,
30}
31
32impl Edit {
33    /// Create an insertion at the given char index.
34    pub fn insert(at_char: usize, text: impl Into<String>) -> Self {
35        Self {
36            range: at_char..at_char,
37            insert: text.into(),
38        }
39    }
40
41    /// Create a deletion for the given char range.
42    pub fn delete(range: core::ops::Range<usize>) -> Self {
43        Self {
44            range,
45            insert: String::new(),
46        }
47    }
48
49    /// Create a replacement for the given char range.
50    pub fn replace(range: core::ops::Range<usize>, text: impl Into<String>) -> Self {
51        Self {
52            range,
53            insert: text.into(),
54        }
55    }
56}