Sticky multibuffer headers (#22391)

https://github.com/user-attachments/assets/92cc5ff7-d8be-4e4b-ac6e-68eb310fffce

Release Notes:

- Multibuffer headers will now stick to the top of the viewport as you
scroll
- Added support for expanding diagnostic excerpts

---------

Co-authored-by: Michael <michael@zed.dev>
This commit is contained in:
Agus Zubiaga 2024-12-24 14:55:25 -03:00 committed by GitHub
parent 4c84600630
commit 45c714110e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 268 additions and 69 deletions

View file

@ -166,7 +166,7 @@ impl ProjectDiagnosticsEditor {
let excerpts = cx.new_model(|cx| MultiBuffer::new(project_handle.read(cx).capability()));
let editor = cx.new_view(|cx| {
let mut editor =
Editor::for_multibuffer(excerpts.clone(), Some(project_handle.clone()), false, cx);
Editor::for_multibuffer(excerpts.clone(), Some(project_handle.clone()), true, cx);
editor.set_vertical_scroll_margin(5, cx);
editor
});

View file

@ -167,10 +167,10 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
editor_blocks(&editor, cx),
[
(DisplayRow(0), FILE_HEADER.into()),
(DisplayRow(2), DIAGNOSTIC_HEADER.into()),
(DisplayRow(15), EXCERPT_HEADER.into()),
(DisplayRow(16), DIAGNOSTIC_HEADER.into()),
(DisplayRow(25), EXCERPT_HEADER.into()),
(DisplayRow(3), DIAGNOSTIC_HEADER.into()),
(DisplayRow(16), EXCERPT_HEADER.into()),
(DisplayRow(18), DIAGNOSTIC_HEADER.into()),
(DisplayRow(27), EXCERPT_HEADER.into()),
]
);
assert_eq!(
@ -184,6 +184,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
// diagnostic group 1
"\n", // primary message
"\n", // padding
"\n", // expand
" let x = vec![];\n",
" let y = vec![];\n",
"\n", // supporting diagnostic
@ -195,6 +196,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
" c(y);\n",
"\n", // supporting diagnostic
" d(x);\n",
"\n", // expand
"\n", // context ellipsis
// diagnostic group 2
"\n", // primary message
@ -206,11 +208,13 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
" a(x);\n",
"\n", // supporting diagnostic
" b(y);\n",
"\n", // expand
"\n", // context ellipsis
" c(y);\n",
" d(x);\n",
"\n", // supporting diagnostic
"}"
"}",
"\n", // expand
)
);
@ -218,7 +222,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
editor.update(cx, |editor, cx| {
assert_eq!(
editor.selections.display_ranges(cx),
[DisplayPoint::new(DisplayRow(12), 6)..DisplayPoint::new(DisplayRow(12), 6)]
[DisplayPoint::new(DisplayRow(13), 6)..DisplayPoint::new(DisplayRow(13), 6)]
);
});
@ -253,12 +257,12 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
editor_blocks(&editor, cx),
[
(DisplayRow(0), FILE_HEADER.into()),
(DisplayRow(2), DIAGNOSTIC_HEADER.into()),
(DisplayRow(7), FILE_HEADER.into()),
(DisplayRow(9), DIAGNOSTIC_HEADER.into()),
(DisplayRow(22), EXCERPT_HEADER.into()),
(DisplayRow(23), DIAGNOSTIC_HEADER.into()),
(DisplayRow(32), EXCERPT_HEADER.into()),
(DisplayRow(3), DIAGNOSTIC_HEADER.into()),
(DisplayRow(8), FILE_HEADER.into()),
(DisplayRow(12), DIAGNOSTIC_HEADER.into()),
(DisplayRow(25), EXCERPT_HEADER.into()),
(DisplayRow(27), DIAGNOSTIC_HEADER.into()),
(DisplayRow(36), EXCERPT_HEADER.into()),
]
);
@ -273,6 +277,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
// diagnostic group 1
"\n", // primary message
"\n", // padding
"\n", // expand
"const a: i32 = 'a';\n",
"\n", // supporting diagnostic
"const b: i32 = c;\n",
@ -284,6 +289,8 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
// diagnostic group 1
"\n", // primary message
"\n", // padding
"\n", // expand
"\n", // expand
" let x = vec![];\n",
" let y = vec![];\n",
"\n", // supporting diagnostic
@ -299,6 +306,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
// diagnostic group 2
"\n", // primary message
"\n", // filename
"\n", // expand
"fn main() {\n",
" let x = vec![];\n",
"\n", // supporting diagnostic
@ -306,11 +314,13 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
" a(x);\n",
"\n", // supporting diagnostic
" b(y);\n",
"\n", // expand
"\n", // context ellipsis
" c(y);\n",
" d(x);\n",
"\n", // supporting diagnostic
"}"
"}",
"\n", // expand
)
);
@ -318,7 +328,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
editor.update(cx, |editor, cx| {
assert_eq!(
editor.selections.display_ranges(cx),
[DisplayPoint::new(DisplayRow(19), 6)..DisplayPoint::new(DisplayRow(19), 6)]
[DisplayPoint::new(DisplayRow(22), 6)..DisplayPoint::new(DisplayRow(22), 6)]
);
});
@ -366,14 +376,14 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
editor_blocks(&editor, cx),
[
(DisplayRow(0), FILE_HEADER.into()),
(DisplayRow(2), DIAGNOSTIC_HEADER.into()),
(DisplayRow(7), EXCERPT_HEADER.into()),
(DisplayRow(8), DIAGNOSTIC_HEADER.into()),
(DisplayRow(13), FILE_HEADER.into()),
(DisplayRow(15), DIAGNOSTIC_HEADER.into()),
(DisplayRow(28), EXCERPT_HEADER.into()),
(DisplayRow(29), DIAGNOSTIC_HEADER.into()),
(DisplayRow(38), EXCERPT_HEADER.into()),
(DisplayRow(3), DIAGNOSTIC_HEADER.into()),
(DisplayRow(8), EXCERPT_HEADER.into()),
(DisplayRow(10), DIAGNOSTIC_HEADER.into()),
(DisplayRow(15), FILE_HEADER.into()),
(DisplayRow(19), DIAGNOSTIC_HEADER.into()),
(DisplayRow(32), EXCERPT_HEADER.into()),
(DisplayRow(34), DIAGNOSTIC_HEADER.into()),
(DisplayRow(43), EXCERPT_HEADER.into()),
]
);
@ -388,6 +398,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
// diagnostic group 1
"\n", // primary message
"\n", // padding
"\n", // expand
"const a: i32 = 'a';\n",
"\n", // supporting diagnostic
"const b: i32 = c;\n",
@ -395,6 +406,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
// diagnostic group 2
"\n", // primary message
"\n", // padding
"\n", // expand
"const a: i32 = 'a';\n",
"const b: i32 = c;\n",
"\n", // supporting diagnostic
@ -406,6 +418,8 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
// diagnostic group 1
"\n", // primary message
"\n", // padding
"\n", // expand
"\n", // expand
" let x = vec![];\n",
" let y = vec![];\n",
"\n", // supporting diagnostic
@ -421,6 +435,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
// diagnostic group 2
"\n", // primary message
"\n", // filename
"\n", // expand
"fn main() {\n",
" let x = vec![];\n",
"\n", // supporting diagnostic
@ -428,11 +443,13 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
" a(x);\n",
"\n", // supporting diagnostic
" b(y);\n",
"\n", // expand
"\n", // context ellipsis
" c(y);\n",
" d(x);\n",
"\n", // supporting diagnostic
"}"
"}",
"\n", // expand
)
);
}
@ -513,7 +530,7 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) {
editor_blocks(&editor, cx),
[
(DisplayRow(0), FILE_HEADER.into()),
(DisplayRow(2), DIAGNOSTIC_HEADER.into()),
(DisplayRow(3), DIAGNOSTIC_HEADER.into()),
]
);
assert_eq!(
@ -524,8 +541,9 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) {
// diagnostic group 1
"\n", // primary message
"\n", // padding
"\n", // expand
"a();\n", //
"b();",
"b();", "\n", // expand
)
);
@ -561,9 +579,9 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) {
editor_blocks(&editor, cx),
[
(DisplayRow(0), FILE_HEADER.into()),
(DisplayRow(2), DIAGNOSTIC_HEADER.into()),
(DisplayRow(6), EXCERPT_HEADER.into()),
(DisplayRow(7), DIAGNOSTIC_HEADER.into()),
(DisplayRow(3), DIAGNOSTIC_HEADER.into()),
(DisplayRow(7), EXCERPT_HEADER.into()),
(DisplayRow(9), DIAGNOSTIC_HEADER.into()),
]
);
assert_eq!(
@ -574,8 +592,10 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) {
// diagnostic group 1
"\n", // primary message
"\n", // padding
"\n", // expand
"a();\n", // location
"b();\n", //
"\n", // expand
"\n", // collapsed context
// diagnostic group 2
"\n", // primary message
@ -583,6 +603,7 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) {
"a();\n", // context
"b();\n", //
"c();", // context
"\n", // expand
)
);
@ -629,9 +650,9 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) {
editor_blocks(&editor, cx),
[
(DisplayRow(0), FILE_HEADER.into()),
(DisplayRow(2), DIAGNOSTIC_HEADER.into()),
(DisplayRow(7), EXCERPT_HEADER.into()),
(DisplayRow(8), DIAGNOSTIC_HEADER.into()),
(DisplayRow(3), DIAGNOSTIC_HEADER.into()),
(DisplayRow(8), EXCERPT_HEADER.into()),
(DisplayRow(10), DIAGNOSTIC_HEADER.into()),
]
);
assert_eq!(
@ -642,9 +663,11 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) {
// diagnostic group 1
"\n", // primary message
"\n", // padding
"\n", // expand
"a();\n", // location
"b();\n", //
"c();\n", // context
"\n", // expand
"\n", // collapsed context
// diagnostic group 2
"\n", // primary message
@ -652,6 +675,7 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) {
"b();\n", // context
"c();\n", //
"d();", // context
"\n", // expand
)
);
@ -687,9 +711,9 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) {
editor_blocks(&editor, cx),
[
(DisplayRow(0), FILE_HEADER.into()),
(DisplayRow(2), DIAGNOSTIC_HEADER.into()),
(DisplayRow(7), EXCERPT_HEADER.into()),
(DisplayRow(8), DIAGNOSTIC_HEADER.into()),
(DisplayRow(3), DIAGNOSTIC_HEADER.into()),
(DisplayRow(8), EXCERPT_HEADER.into()),
(DisplayRow(10), DIAGNOSTIC_HEADER.into()),
]
);
assert_eq!(
@ -700,9 +724,11 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) {
// diagnostic group 1
"\n", // primary message
"\n", // padding
"\n", // expand
"b();\n", // location
"c();\n", //
"d();\n", // context
"\n", // expand
"\n", // collapsed context
// diagnostic group 2
"\n", // primary message
@ -710,6 +736,7 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) {
"c();\n", // context
"d();\n", //
"e();", // context
"\n", // expand
)
);
}