Last active
November 2, 2025 16:05
-
-
Save lmmx/c4ecea5108fb4997ff01d0e3a3b610c2 to your computer and use it in GitHub Desktop.
`ropey::Rope` hello world with string diff
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env rust-script | |
| //! ```cargo | |
| //! [dependencies] | |
| //! ropey = "1.6" | |
| //! smartstring = "1.0" | |
| //! ``` | |
| use ropey::Rope; | |
| use smartstring::alias::String as Tendril; | |
| // Your basic change: (from_char_idx, to_char_idx, replacement_text) | |
| pub type Change = (usize, usize, Option<Tendril>); | |
| fn apply_change(rope: &mut Rope, change: Change) { | |
| let (from, to, text) = change; | |
| // Remove the range | |
| rope.remove(from..to); | |
| // Insert new text if provided | |
| if let Some(text) = text { | |
| rope.insert(from, text.as_str()); | |
| } | |
| } | |
| fn main() { | |
| let mut rope = Rope::from_str("hello world"); | |
| println!("Original: {}", rope); | |
| // Delete "world" (chars 6-11) | |
| apply_change(&mut rope, (6, 11, None)); | |
| println!("After delete: {}", rope); // "hello " | |
| // Insert "rust" at position 6 | |
| apply_change(&mut rope, (6, 6, Some("rust".into()))); | |
| println!("After insert: {}", rope); // "hello rust" | |
| // Replace "hello" with "hey" (chars 0-5) | |
| apply_change(&mut rope, (0, 5, Some("hey".into()))); | |
| println!("After replace: {}", rope); // "hey rust" | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env rust-script | |
| //! ```cargo | |
| //! [dependencies] | |
| //! smartstring = "1.0" | |
| //! ``` | |
| use smartstring::SmartString; | |
| pub type Tendril = SmartString<smartstring::LazyCompact>; | |
| fn main() { | |
| let mut s: Tendril = "hi".into(); | |
| println!("1. Small: inline={}", s.is_inline()); | |
| s.push_str(" grows beyond inline capacity now"); | |
| println!("2. Grown: inline={} cap={}", s.is_inline(), s.capacity()); | |
| s.truncate(5); | |
| println!("3. Truncated to 5 chars: inline={} cap={}", s.is_inline(), s.capacity()); | |
| s.push_str("x"); | |
| println!("4. Added char: inline={} cap={}", s.is_inline(), s.capacity()); | |
| } |
./demo_lazycompact.rs 1. Small: inline=true
2. Grown: inline=false cap=46
3. Truncated to 5 chars: inline=false cap=46
4. Added char: inline=false cap=46
Demonstrates LazyCompact's allocation strategy for editor-style string operations:
- Small strings inline - no heap allocation for "hi"
- Grow → heap - allocates once when exceeding inline capacity
- Shrink → stays heap - keeps allocation even when short again (lazy!)
- Reuse allocation - adding more chars reuses existing capacity
Avoids allocation thrashing when strings repeatedly grow/shrink across the inline threshold - critical for editor undo/redo performance.
Note as seen in helix-core
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Demonstrates applying three types of edits to a Rope using the
Changetype:Shows the core primitive for a file patching system.