Skip to main content

redox_core/
lib.rs

1//! Core editor primitives.
2//!
3//! This crate provides a rope-based text buffer (via `ropey`) and small, focused
4//! navigation utilities suitable for implementing a Vim-like editor.
5//!
6//! Notes on indexing
7//! - `ropey::Rope` is UTF-8 text stored as a rope.
8//! - Most editing operations are most naturally expressed in **char indices**
9//!   (`usize` counts of Unicode scalar values), because `ropey` exposes many APIs
10//!   in terms of `char` offsets.
11//! - The UI may need **byte indices** for interoperability with external data,
12//!   but those are not used as the primary index type in this crate.
13
14pub const SOFT_TAB_WIDTH: usize = 4;
15pub const SOFT_TAB: &str = "    ";
16
17pub mod buffer;
18pub mod fuzzy;
19pub mod io;
20pub mod logic;
21pub mod motion;
22pub mod session;
23pub mod text;
24
25// Prefer using the rope-backed buffer implementation from `buffer`.
26// Re-export the common types here for ergonomic access by downstream crates.
27pub use buffer::{
28    DelimiterKind, Edit, EditBatchSummary, Pos, Selection, TextBuffer, TextObjectEditPlan,
29    TextObjectKind, TextObjectScope, TextObjectSpec, VisualModeKind, VisualSelectionEditPlan,
30};
31pub use fuzzy::{
32    FuzzyMatch, FuzzyQuery, PathMatchScore, compare_path_match_scores, fuzzy_match_ranges,
33    path_match_score,
34};
35pub use session::{
36    BufferId, BufferKind, BufferLoadPhase, BufferLoadStatus, BufferMeta, BufferSummary,
37    EditorSession,
38};
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43
44    #[test]
45    fn empty_buffer_has_one_line() {
46        let b = TextBuffer::new();
47        assert_eq!(b.len_lines(), 1);
48        assert_eq!(b.len_chars(), 0);
49    }
50
51    #[test]
52    fn insert_and_delete_selection_smoke() {
53        let mut b = TextBuffer::from_str("ab");
54
55        let sel = Selection::empty(Pos::new(0, 2));
56        let new_cursor = b.insert(sel.cursor, "c");
57        assert_eq!(b.to_string(), "abc");
58        assert_eq!(new_cursor, Pos::new(0, 3));
59
60        let sel2 = Selection::new(Pos::new(0, 1), Pos::new(0, 2));
61        let (cur, did) = b.delete_selection(sel2);
62        assert!(did);
63        assert_eq!(cur, Pos::new(0, 1));
64        assert_eq!(b.to_string(), "ac");
65    }
66}