Skip to content

Instantly share code, notes, and snippets.

@lmmx
Last active November 2, 2025 16:05
Show Gist options
  • Save lmmx/c4ecea5108fb4997ff01d0e3a3b610c2 to your computer and use it in GitHub Desktop.
Save lmmx/c4ecea5108fb4997ff01d0e3a3b610c2 to your computer and use it in GitHub Desktop.
`ropey::Rope` hello world with string diff
#!/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"
}
#!/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());
}
@lmmx
Copy link
Author

lmmx commented Nov 2, 2025

./demo.rs 
Original: hello world
After delete: hello 
After insert: hello rust
After replace: hey rust

Demonstrates applying three types of edits to a Rope using the Change type:

  1. Delete - remove text (delete "world")
  2. Insert - add text at position (insert "rust")
  3. Replace - swap text range (replace "hello" with "hey")

Shows the core primitive for a file patching system.

@lmmx
Copy link
Author

lmmx commented Nov 2, 2025

./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:

  1. Small strings inline - no heap allocation for "hi"
  2. Grow → heap - allocates once when exceeding inline capacity
  3. Shrink → stays heap - keeps allocation even when short again (lazy!)
  4. 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