@@ -29058,6 +29058,95 @@ async fn test_sticky_scroll(cx: &mut TestAppContext) {
2905829058 assert_eq!(sticky_headers(10.0), vec![]);
2905929059}
2906029060
29061+ #[gpui::test]
29062+ async fn test_sticky_scroll_with_expanded_deleted_diff_hunks(
29063+ executor: BackgroundExecutor,
29064+ cx: &mut TestAppContext,
29065+ ) {
29066+ init_test(cx, |_| {});
29067+ let mut cx = EditorTestContext::new(cx).await;
29068+
29069+ let diff_base = indoc! {"
29070+ fn foo() {
29071+ let a = 1;
29072+ let b = 2;
29073+ let c = 3;
29074+ let d = 4;
29075+ let e = 5;
29076+ }
29077+ "};
29078+
29079+ let buffer = indoc! {"
29080+ ˇfn foo() {
29081+ }
29082+ "};
29083+
29084+ cx.set_state(&buffer);
29085+
29086+ cx.update_editor(|e, _, cx| {
29087+ e.buffer()
29088+ .read(cx)
29089+ .as_singleton()
29090+ .unwrap()
29091+ .update(cx, |buffer, cx| {
29092+ buffer.set_language(Some(rust_lang()), cx);
29093+ })
29094+ });
29095+
29096+ cx.set_head_text(diff_base);
29097+ executor.run_until_parked();
29098+
29099+ cx.update_editor(|editor, window, cx| {
29100+ editor.expand_all_diff_hunks(&ExpandAllDiffHunks, window, cx);
29101+ });
29102+ executor.run_until_parked();
29103+
29104+ // After expanding, the display should look like:
29105+ // row 0: fn foo() {
29106+ // row 1: - let a = 1; (deleted)
29107+ // row 2: - let b = 2; (deleted)
29108+ // row 3: - let c = 3; (deleted)
29109+ // row 4: - let d = 4; (deleted)
29110+ // row 5: - let e = 5; (deleted)
29111+ // row 6: }
29112+ //
29113+ // fn foo() spans display rows 0-6. Scrolling into the deleted region
29114+ // (rows 1-5) should still show fn foo() as a sticky header.
29115+
29116+ let fn_foo = Point { row: 0, column: 0 };
29117+
29118+ let mut sticky_headers = |offset: ScrollOffset| {
29119+ cx.update_editor(|e, window, cx| {
29120+ e.scroll(gpui::Point { x: 0., y: offset }, None, window, cx);
29121+ });
29122+ cx.run_until_parked();
29123+ cx.update_editor(|e, window, cx| {
29124+ EditorElement::sticky_headers(&e, &e.snapshot(window, cx))
29125+ .into_iter()
29126+ .map(
29127+ |StickyHeader {
29128+ start_point,
29129+ offset,
29130+ ..
29131+ }| { (start_point, offset) },
29132+ )
29133+ .collect::<Vec<_>>()
29134+ })
29135+ };
29136+
29137+ assert_eq!(sticky_headers(0.0), vec![]);
29138+ assert_eq!(sticky_headers(0.5), vec![(fn_foo, 0.0)]);
29139+ assert_eq!(sticky_headers(1.0), vec![(fn_foo, 0.0)]);
29140+ // Scrolling into deleted lines: fn foo() should still be a sticky header.
29141+ assert_eq!(sticky_headers(2.0), vec![(fn_foo, 0.0)]);
29142+ assert_eq!(sticky_headers(3.0), vec![(fn_foo, 0.0)]);
29143+ assert_eq!(sticky_headers(4.0), vec![(fn_foo, 0.0)]);
29144+ assert_eq!(sticky_headers(5.0), vec![(fn_foo, 0.0)]);
29145+ assert_eq!(sticky_headers(5.5), vec![(fn_foo, -0.5)]);
29146+ // Past the closing brace: no more sticky header.
29147+ assert_eq!(sticky_headers(6.0), vec![]);
29148+ }
29149+
2906129150#[gpui::test]
2906229151fn test_relative_line_numbers(cx: &mut TestAppContext) {
2906329152 init_test(cx, |_| {});
0 commit comments