MarkdownDocument: one caret for every mode, pressed blocks kept across write-backs, preview read only, keyboard reach, history capped on every path
CI / site (push) Successful in 25s
CI / platforms (windows-latest) (push) Successful in 4m37s
CI / crate (push) Failing after 26m50s
CI / platforms (ubuntu-24.04) (push) Canceled after 0s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-12 01:14:06 -04:00
1 parent 2b6f5513aa
commit fc181b44c2
13 files changed
+590 -242

No files matched your search

+34 -8
View File
@@ -144,16 +144,26 @@ impl<S> History<S> {
Some(next)
}
/// Drops oldest undo steps past `budget`; returns how many.
/// The size all steps hold, as `size` measures one.
pub fn held(&self, size: impl Fn(&S) -> usize) -> usize {
self.undo.iter().chain(&self.redo).map(size).sum()
}
/// Drops oldest undo, then farthest redo, past `budget`; how many.
pub fn trim(&mut self, budget: usize, size: impl Fn(&S) -> usize) -> usize {
let mut held: usize = self.undo.iter().chain(&self.redo).map(&size).sum();
let mut dropped = 0;
while held > budget && dropped < self.undo.len() {
held -= size(&self.undo[dropped]);
dropped += 1;
let mut held = self.held(&size);
let (mut undone, mut redone) = (0, 0);
while held > budget && undone < self.undo.len() {
held -= size(&self.undo[undone]);
undone += 1;
}
self.undo.drain(..dropped);
dropped
while held > budget && redone < self.redo.len() {
held -= size(&self.redo[redone]);
redone += 1;
}
self.undo.drain(..undone);
self.redo.drain(..redone);
undone + redone
}
}
@@ -174,6 +184,22 @@ mod tests {
assert_eq!(history.trim(100, String::len), 0);
}
#[test]
fn trimming_drops_the_farthest_redo_when_undo_is_spent() {
let mut history = History::default();
history.record("small".to_string(), false);
// Undo leaves the large text to redo.
assert_eq!(history.undo("x".repeat(20)), Some("small".to_string()));
history.redo.insert(0, "y".repeat(20));
assert_eq!(history.trim(25, String::len), 1);
assert_eq!(
history.redo("small".into()),
Some("x".repeat(20)),
"the nearest stays"
);
assert_eq!(history.redo("x".repeat(20)), None);
}
#[test]
fn graphemes_keep_clusters_whole() {
let text = "ae\u{301}🇯🇵z";