diff --git a/src/documents/document/mod.rs b/src/documents/document/mod.rs index 57b9a22..d5cb424 100644 --- a/src/documents/document/mod.rs +++ b/src/documents/document/mod.rs @@ -206,10 +206,20 @@ impl MarkdownDocument { .update(cx, |editor, cx| editor.set_text(text, cx)); } - /// Replaces the text, undo afresh; open typing drops. + /// New text, undo afresh; caret and top line stay. pub fn reset(&mut self, text: impl Into, cx: &mut Context) { + let ((line, column), top) = (self.caret(cx), self.top_line(cx)); self.drop_open(cx); self.editor.update(cx, |editor, cx| editor.reset(text, cx)); + self.set_caret(line, column, cx); + // Placed once the new text is read. + self.asks += 1; + self.top = Some(Placement { + line: top, + ask: self.asks, + placing: false, + }); + cx.notify(); } /// The headings as last read, with lines from zero. diff --git a/src/documents/document/tests/place.rs b/src/documents/document/tests/place.rs index 18ce4b4..4e6613b 100644 --- a/src/documents/document/tests/place.rs +++ b/src/documents/document/tests/place.rs @@ -180,3 +180,21 @@ x- one" }); assert_eq!(outline, [("Lift".to_string(), 0)]); } + +#[gpui::test] +fn a_reset_keeps_the_caret_and_the_top_line(cx: &mut TestAppContext) { + let lines: String = (0..60).map(|n| format!("Line {n}\n\n")).collect(); + let (document, cx) = open(&lines, MarkdownMode::Source, cx); + document.update_in(cx, |document, window, cx| { + document.set_caret(40, 2, cx); + document.set_top_line(30, window, cx); + }); + frames(cx); + let changed: String = (0..60).map(|n| format!("Row {n}\n\n")).collect(); + document.update(cx, |document, cx| document.reset(changed, cx)); + frames(cx); + let (caret, top) = document.read_with(cx, |document, cx| { + (document.caret(cx), document.top_line(cx)) + }); + assert_eq!((caret, top), ((40, 2), 30)); +}