MarkdownDocument: one caret for every mode, pressed blocks kept across write-backs, preview read only, keyboard reach, history capped on every path
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
2b6f5513aa
commit
fc181b44c2
13 files changed
+590
-242
No files matched your search
@@ -336,6 +336,7 @@ impl CodeEditor {
|
||||
}
|
||||
if let Some(previous) = self.history.undo(self.snapshot()) {
|
||||
self.restore(previous, cx);
|
||||
self.cap_history();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,6 +346,7 @@ impl CodeEditor {
|
||||
}
|
||||
if let Some(next) = self.history.redo(self.snapshot()) {
|
||||
self.restore(next, cx);
|
||||
self.cap_history();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ impl CodeEditor {
|
||||
&& start.text != self.buffer.text()
|
||||
{
|
||||
self.history.record(start, false);
|
||||
self.cap_history();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,16 @@ impl CodeEditor {
|
||||
self.restart_blink(cx);
|
||||
}
|
||||
|
||||
/// Keeps undo within its byte budget, logging what went.
|
||||
pub(crate) fn cap_history(&mut self) {
|
||||
let dropped = self
|
||||
.history
|
||||
.trim(self.history_bytes, |step| step.text.len());
|
||||
if dropped > 0 {
|
||||
log::info!("code editor: {dropped} far undo steps dropped");
|
||||
}
|
||||
}
|
||||
|
||||
/// A line's colors, as the owner or as code.
|
||||
pub(crate) fn line_colors(&self, text: &str, cx: &App) -> Vec<(Range<usize>, HighlightStyle)> {
|
||||
let Some(LineHighlighter(highlight)) = &self.options.highlighter else {
|
||||
|
||||
+4
-6
@@ -103,6 +103,8 @@ pub struct CodeEditor {
|
||||
pub(crate) buffer: Buffer,
|
||||
pub(crate) selections: Vec<Selection>,
|
||||
pub(crate) history: History<Snapshot>,
|
||||
/// Undo keeps at most this many bytes of text.
|
||||
pub(crate) history_bytes: usize,
|
||||
pub(crate) focus: FocusHandle,
|
||||
pub(crate) scroll: UniformListScrollHandle,
|
||||
pub(crate) folded: BTreeSet<usize>,
|
||||
@@ -172,6 +174,7 @@ impl CodeEditor {
|
||||
buffer: Buffer::new(text),
|
||||
selections: vec![Selection::caret(0)],
|
||||
history: History::default(),
|
||||
history_bytes: super::prose::HISTORY_BYTES,
|
||||
focus,
|
||||
scroll: UniformListScrollHandle::new(),
|
||||
folded: BTreeSet::new(),
|
||||
@@ -432,12 +435,7 @@ impl CodeEditor {
|
||||
if before.text != self.buffer.text() {
|
||||
if self.composing.is_none() {
|
||||
self.history.record(before, typing);
|
||||
let dropped = self
|
||||
.history
|
||||
.trim(super::prose::HISTORY_BYTES, |step| step.text.len());
|
||||
if dropped > 0 {
|
||||
log::info!("code editor: {dropped} oldest undo steps dropped");
|
||||
}
|
||||
self.cap_history();
|
||||
}
|
||||
self.marks.ghost = None;
|
||||
self.folded.retain(|line| *line < self.buffer.lines());
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
use gpui::{EntityInputHandler, TestAppContext};
|
||||
|
||||
use super::editor;
|
||||
|
||||
/// Bytes of text all undo and redo steps hold.
|
||||
fn held(editor: &super::CodeEditor) -> usize {
|
||||
editor.history.held(|step| step.text.len())
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn compositions_keep_undo_within_its_budget(cx: &mut TestAppContext) {
|
||||
let (editor, cx) = editor(&"x".repeat(100), cx);
|
||||
editor.update_in(cx, |editor, window, cx| {
|
||||
editor.history_bytes = 250;
|
||||
for word in ["a", "b", "c", "d"] {
|
||||
editor.replace_and_mark_text_in_range(None, word, None, window, cx);
|
||||
editor.unmark_text(window, cx);
|
||||
}
|
||||
assert!(held(editor) <= 250, "{} bytes held", held(editor));
|
||||
assert!(editor.history.can_undo(), "the nearest steps stay");
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn undo_keeps_redo_within_its_budget(cx: &mut TestAppContext) {
|
||||
let (editor, cx) = editor("small", cx);
|
||||
editor.update(cx, |editor, cx| {
|
||||
editor.history_bytes = 50;
|
||||
editor.edit([(0..5, "y".repeat(80))], cx);
|
||||
editor.undo(cx);
|
||||
assert_eq!(editor.text(), "small");
|
||||
assert!(!editor.history.can_redo(), "a redo past the budget went");
|
||||
});
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
mod history;
|
||||
mod stale;
|
||||
|
||||
use std::{cell::Cell, rc::Rc, time::Duration};
|
||||
|
||||
Reference in new issue
Block a user