Update block diagnostics (#28006)
Release Notes: - "Block" diagnostics (that show up in the diagnostics view, or when using `f8`/`shift-f8`) are rendered more clearly - `f8`/`shift-f8` now always go to the "next" or "prev" diagnostic, regardless of the state of the editor  --------- Co-authored-by: Kirill Bulatov <mail4score@gmail.com> Co-authored-by: Julia Ryan <juliaryan3.14@gmail.com>
This commit is contained in:
parent
ccf9aef767
commit
afabcd1547
17 changed files with 1794 additions and 1987 deletions
|
@ -1,18 +1,25 @@
|
|||
pub mod editor_lsp_test_context;
|
||||
pub mod editor_test_context;
|
||||
|
||||
use std::{rc::Rc, sync::LazyLock};
|
||||
|
||||
pub use crate::rust_analyzer_ext::expand_macro_recursively;
|
||||
use crate::{
|
||||
DisplayPoint, Editor, EditorMode, FoldPlaceholder, MultiBuffer,
|
||||
display_map::{DisplayMap, DisplaySnapshot, ToDisplayPoint},
|
||||
display_map::{
|
||||
Block, BlockPlacement, CustomBlockId, DisplayMap, DisplayRow, DisplaySnapshot,
|
||||
ToDisplayPoint,
|
||||
},
|
||||
};
|
||||
use collections::HashMap;
|
||||
use gpui::{
|
||||
AppContext as _, Context, Entity, Font, FontFeatures, FontStyle, FontWeight, Pixels, Window,
|
||||
font,
|
||||
AppContext as _, Context, Entity, EntityId, Font, FontFeatures, FontStyle, FontWeight, Pixels,
|
||||
VisualTestContext, Window, font, size,
|
||||
};
|
||||
use multi_buffer::ToPoint;
|
||||
use pretty_assertions::assert_eq;
|
||||
use project::Project;
|
||||
use std::sync::LazyLock;
|
||||
use ui::{App, BorrowAppContext, px};
|
||||
use util::test::{marked_text_offsets, marked_text_ranges};
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -122,3 +129,126 @@ pub(crate) fn build_editor_with_project(
|
|||
) -> Editor {
|
||||
Editor::new(EditorMode::full(), buffer, Some(project), window, cx)
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct TestBlockContent(
|
||||
HashMap<(EntityId, CustomBlockId), Rc<dyn Fn(&mut VisualTestContext) -> String>>,
|
||||
);
|
||||
|
||||
impl gpui::Global for TestBlockContent {}
|
||||
|
||||
pub fn set_block_content_for_tests(
|
||||
editor: &Entity<Editor>,
|
||||
id: CustomBlockId,
|
||||
cx: &mut App,
|
||||
f: impl Fn(&mut VisualTestContext) -> String + 'static,
|
||||
) {
|
||||
cx.update_default_global::<TestBlockContent, _>(|bc, _| {
|
||||
bc.0.insert((editor.entity_id(), id), Rc::new(f))
|
||||
});
|
||||
}
|
||||
|
||||
pub fn block_content_for_tests(
|
||||
editor: &Entity<Editor>,
|
||||
id: CustomBlockId,
|
||||
cx: &mut VisualTestContext,
|
||||
) -> Option<String> {
|
||||
let f = cx.update(|_, cx| {
|
||||
cx.default_global::<TestBlockContent>()
|
||||
.0
|
||||
.get(&(editor.entity_id(), id))
|
||||
.cloned()
|
||||
})?;
|
||||
Some(f(cx))
|
||||
}
|
||||
|
||||
pub fn editor_content_with_blocks(editor: &Entity<Editor>, cx: &mut VisualTestContext) -> String {
|
||||
cx.draw(
|
||||
gpui::Point::default(),
|
||||
size(px(3000.0), px(3000.0)),
|
||||
|_, _| editor.clone(),
|
||||
);
|
||||
let (snapshot, mut lines, blocks) = editor.update_in(cx, |editor, window, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let text = editor.display_text(cx);
|
||||
let lines = text.lines().map(|s| s.to_string()).collect::<Vec<String>>();
|
||||
let blocks = snapshot
|
||||
.blocks_in_range(DisplayRow(0)..snapshot.max_point().row())
|
||||
.map(|(row, block)| (row, block.clone()))
|
||||
.collect::<Vec<_>>();
|
||||
(snapshot, lines, blocks)
|
||||
});
|
||||
for (row, block) in blocks {
|
||||
match block {
|
||||
Block::Custom(custom_block) => {
|
||||
if let BlockPlacement::Near(x) = &custom_block.placement {
|
||||
if snapshot.intersects_fold(x.to_point(&snapshot.buffer_snapshot)) {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let content = block_content_for_tests(&editor, custom_block.id, cx)
|
||||
.expect("block content not found");
|
||||
// 2: "related info 1 for diagnostic 0"
|
||||
if let Some(height) = custom_block.height {
|
||||
if height == 0 {
|
||||
lines[row.0 as usize - 1].push_str(" § ");
|
||||
lines[row.0 as usize - 1].push_str(&content);
|
||||
} else {
|
||||
let block_lines = content.lines().collect::<Vec<_>>();
|
||||
assert_eq!(block_lines.len(), height as usize);
|
||||
lines[row.0 as usize].push_str("§ ");
|
||||
lines[row.0 as usize].push_str(block_lines[0].trim_end());
|
||||
for i in 1..height as usize {
|
||||
lines[row.0 as usize + i].push_str("§ ");
|
||||
lines[row.0 as usize + i].push_str(block_lines[i].trim_end());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Block::FoldedBuffer {
|
||||
first_excerpt,
|
||||
height,
|
||||
} => {
|
||||
lines[row.0 as usize].push_str(&cx.update(|_, cx| {
|
||||
format!(
|
||||
"§ {}",
|
||||
first_excerpt
|
||||
.buffer
|
||||
.file()
|
||||
.unwrap()
|
||||
.file_name(cx)
|
||||
.to_string_lossy()
|
||||
)
|
||||
}));
|
||||
for row in row.0 + 1..row.0 + height {
|
||||
lines[row as usize].push_str("§ -----");
|
||||
}
|
||||
}
|
||||
Block::ExcerptBoundary {
|
||||
excerpt,
|
||||
height,
|
||||
starts_new_buffer,
|
||||
} => {
|
||||
if starts_new_buffer {
|
||||
lines[row.0 as usize].push_str(&cx.update(|_, cx| {
|
||||
format!(
|
||||
"§ {}",
|
||||
excerpt
|
||||
.buffer
|
||||
.file()
|
||||
.unwrap()
|
||||
.file_name(cx)
|
||||
.to_string_lossy()
|
||||
)
|
||||
}));
|
||||
} else {
|
||||
lines[row.0 as usize].push_str("§ -----")
|
||||
}
|
||||
for row in row.0 + 1..row.0 + height {
|
||||
lines[row as usize].push_str("§ -----");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lines.join("\n")
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue