diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 826376766af5d17bc8eadecf2a7358452f98ba4a..e9efa4046a39ea44f6d0818b4b7cf9b879aa63b2 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -105,33 +105,40 @@ impl ProjectDiagnosticsEditor { let excerpt_start = Point::new(range.start.row.saturating_sub(1), 0); let excerpt_end = snapshot .clip_point(Point::new(range.end.row + 1, u32::MAX), Bias::Left); + let excerpt_id = excerpts.push_excerpt( + ExcerptProperties { + buffer: &buffer, + range: excerpt_start..excerpt_end, + }, + excerpts_cx, + ); - let mut excerpt = ExcerptProperties { - buffer: &buffer, - range: excerpt_start..excerpt_end, - header_height: 0, - render_header: None, - }; - + let header_position = (excerpt_id.clone(), language::Anchor::min()); if is_first_excerpt { let primary = &group.entries[group.primary_ix].diagnostic; let mut header = primary.clone(); header.message = primary.message.split('\n').next().unwrap().to_string(); - excerpt.header_height = 2; - excerpt.render_header = Some(diagnostic_header_renderer( - buffer.clone(), - header, - self.build_settings.clone(), - )); + blocks.push(BlockProperties { + position: header_position, + height: 2, + render: diagnostic_header_renderer( + buffer.clone(), + header, + self.build_settings.clone(), + ), + disposition: BlockDisposition::Above, + }); } else { - excerpt.header_height = 1; - excerpt.render_header = - Some(context_header_renderer(self.build_settings.clone())); + blocks.push(BlockProperties { + position: header_position, + height: 1, + render: context_header_renderer(self.build_settings.clone()), + disposition: BlockDisposition::Above, + }); } is_first_excerpt = false; - let excerpt_id = excerpts.push_excerpt(excerpt, excerpts_cx); for entry in &group.entries[*start_ix..ix] { let mut diagnostic = entry.diagnostic.clone(); if diagnostic.is_primary { diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index 589ed36c3bc811891ae58b9916ff8094ce7f1038..5f879ef1638e08a5a14abee8eb6d36fcd3e40fac 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -240,12 +240,11 @@ impl BlockMap { Ok(ix) | Err(ix) => last_block_ix + ix, }; - let new_buffer_end; let end_block_ix = if new_end.0 > wrap_snapshot.max_point().row() { - new_buffer_end = wrap_snapshot.buffer_snapshot().max_point() + Point::new(1, 0); self.blocks.len() } else { - new_buffer_end = wrap_snapshot.to_point(WrapPoint::new(new_end.0, 0), Bias::Left); + let new_buffer_end = + wrap_snapshot.to_point(WrapPoint::new(new_end.0, 0), Bias::Left); let end_anchor = buffer.anchor_before(new_buffer_end); match self.blocks[start_block_ix..].binary_search_by(|probe| { probe @@ -260,24 +259,6 @@ impl BlockMap { last_block_ix = end_block_ix; debug_assert!(blocks_in_edit.is_empty()); - blocks_in_edit.extend( - wrap_snapshot - .buffer_snapshot() - .excerpt_headers_in_range(new_buffer_start.row..new_buffer_end.row) - .map(|(start_row, header_height, render_header)| { - ( - start_row, - 0, - Arc::new(Block { - id: Default::default(), - position: Anchor::min(), - height: header_height, - render: Mutex::new(Arc::new(move |cx| render_header(cx))), - disposition: BlockDisposition::Above, - }), - ) - }), - ); blocks_in_edit.extend( self.blocks[start_block_ix..end_block_ix] .iter() diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 8992772577fa76af7a0ae2ae7908286726cb5715..b2243a41516ac2ede06aa48ebbf64414d1377319 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -28,9 +28,7 @@ use language::{ TransactionId, }; pub use multi_buffer::{Anchor, ExcerptProperties, MultiBuffer}; -use multi_buffer::{ - AnchorRangeExt, MultiBufferChunks, MultiBufferSnapshot, RenderHeaderFn, ToOffset, ToPoint, -}; +use multi_buffer::{AnchorRangeExt, MultiBufferChunks, MultiBufferSnapshot, ToOffset, ToPoint}; use postage::watch; use serde::{Deserialize, Serialize}; use smallvec::SmallVec; @@ -3787,12 +3785,12 @@ pub fn diagnostic_header_renderer( buffer: ModelHandle, diagnostic: Diagnostic, build_settings: BuildSettings, -) -> RenderHeaderFn { +) -> RenderBlock { Arc::new(move |cx| { let settings = build_settings(cx); let mut text_style = settings.style.text.clone(); text_style.color = diagnostic_style(diagnostic.severity, true, &settings.style).text; - let file_path = if let Some(file) = buffer.read(cx).file() { + let file_path = if let Some(file) = buffer.read(&**cx).file() { file.path().to_string_lossy().to_string() } else { "untitled".to_string() @@ -3805,7 +3803,7 @@ pub fn diagnostic_header_renderer( }) } -pub fn context_header_renderer(build_settings: BuildSettings) -> RenderHeaderFn { +pub fn context_header_renderer(build_settings: BuildSettings) -> RenderBlock { Arc::new(move |cx| { let settings = build_settings(cx); let text_style = settings.style.text.clone(); @@ -5910,8 +5908,6 @@ mod tests { ExcerptProperties { buffer: &buffer, range: Point::new(0, 0)..Point::new(0, 4), - header_height: 0, - render_header: None, }, cx, ); @@ -5919,8 +5915,6 @@ mod tests { ExcerptProperties { buffer: &buffer, range: Point::new(1, 0)..Point::new(1, 4), - header_height: 0, - render_header: None, }, cx, ); @@ -5964,8 +5958,6 @@ mod tests { ExcerptProperties { buffer: &buffer, range: Point::new(0, 0)..Point::new(1, 4), - header_height: 0, - render_header: None, }, cx, ); @@ -5973,8 +5965,6 @@ mod tests { ExcerptProperties { buffer: &buffer, range: Point::new(1, 0)..Point::new(2, 4), - header_height: 0, - render_header: None, }, cx, ); diff --git a/crates/editor/src/movement.rs b/crates/editor/src/movement.rs index 00b5140a6cd6520d50d1dd4ac7fcd8b0f576c369..217b1e63e4f53dc1ac0766950bf9d31cf03bfa1c 100644 --- a/crates/editor/src/movement.rs +++ b/crates/editor/src/movement.rs @@ -238,8 +238,13 @@ fn char_kind(c: char) -> CharKind { #[cfg(test)] mod tests { use super::*; - use crate::{Buffer, DisplayMap, ExcerptProperties, MultiBuffer}; + use crate::{ + display_map::{BlockDisposition, BlockProperties}, + Buffer, DisplayMap, ExcerptProperties, MultiBuffer, + }; + use gpui::{elements::Empty, Element}; use language::Point; + use std::sync::Arc; #[gpui::test] fn test_move_up_and_down_with_excerpts(cx: &mut gpui::MutableAppContext) { @@ -250,31 +255,59 @@ mod tests { .unwrap(); let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndefg\nhijkl\nmn", cx)); + let mut excerpt1_header_position = None; + let mut excerpt2_header_position = None; let multibuffer = cx.add_model(|cx| { let mut multibuffer = MultiBuffer::new(0); - multibuffer.push_excerpt( + let excerpt1_id = multibuffer.push_excerpt( ExcerptProperties { buffer: &buffer, range: Point::new(0, 0)..Point::new(1, 4), - header_height: 2, - render_header: None, }, cx, ); - multibuffer.push_excerpt( + let excerpt2_id = multibuffer.push_excerpt( ExcerptProperties { buffer: &buffer, range: Point::new(2, 0)..Point::new(3, 2), - header_height: 3, - render_header: None, }, cx, ); + + excerpt1_header_position = Some( + multibuffer + .read(cx) + .anchor_in_excerpt(excerpt1_id, language::Anchor::min()), + ); + excerpt2_header_position = Some( + multibuffer + .read(cx) + .anchor_in_excerpt(excerpt2_id, language::Anchor::min()), + ); multibuffer }); let display_map = cx.add_model(|cx| DisplayMap::new(multibuffer, 2, font_id, 14.0, None, cx)); + display_map.update(cx, |display_map, cx| { + display_map.insert_blocks( + [ + BlockProperties { + position: excerpt1_header_position.unwrap(), + height: 2, + render: Arc::new(|_| Empty::new().boxed()), + disposition: BlockDisposition::Above, + }, + BlockProperties { + position: excerpt2_header_position.unwrap(), + height: 3, + render: Arc::new(|_| Empty::new().boxed()), + disposition: BlockDisposition::Above, + }, + ], + cx, + ) + }); let snapshot = display_map.update(cx, |map, cx| map.snapshot(cx)); assert_eq!(snapshot.text(), "\n\nabc\ndefg\n\n\n\nhijkl\nmn"); diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index a642778f42bde5b512442c05ff211dc72dace908..301499f144c2168195c58e6eea663f4a159e77d7 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -4,7 +4,7 @@ pub use anchor::{Anchor, AnchorRangeExt}; use anyhow::Result; use clock::ReplicaId; use collections::{HashMap, HashSet}; -use gpui::{AppContext, ElementBox, Entity, ModelContext, ModelHandle, Task}; +use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task}; use language::{ Buffer, BufferChunks, BufferSnapshot, Chunk, DiagnosticEntry, Event, File, Language, Selection, ToOffset as _, ToPoint as _, TransactionId, @@ -86,13 +86,9 @@ pub struct MultiBufferSnapshot { has_conflict: bool, } -pub type RenderHeaderFn = Arc ElementBox>; - pub struct ExcerptProperties<'a, T> { pub buffer: &'a ModelHandle, pub range: Range, - pub header_height: u8, - pub render_header: Option, } #[derive(Clone)] @@ -101,9 +97,7 @@ struct Excerpt { buffer_id: usize, buffer: BufferSnapshot, range: Range, - render_header: Option, text_summary: TextSummary, - header_height: u8, has_trailing_newline: bool, } @@ -167,8 +161,6 @@ impl MultiBuffer { ExcerptProperties { buffer: &buffer, range: text::Anchor::min()..text::Anchor::max(), - header_height: 0, - render_header: None, }, cx, ); @@ -229,8 +221,6 @@ impl MultiBuffer { ExcerptProperties { buffer: buffer_handle, range: start_ix..end_ix, - header_height, - render_header: None, }, cx, ); @@ -618,15 +608,7 @@ impl MultiBuffer { ); let id = ExcerptId::between(&prev_id.unwrap_or(ExcerptId::min()), &ExcerptId::max()); - let excerpt = Excerpt::new( - id.clone(), - buffer.id(), - buffer_snapshot, - range, - props.header_height, - props.render_header, - false, - ); + let excerpt = Excerpt::new(id.clone(), buffer.id(), buffer_snapshot, range, false); snapshot.excerpts.push(excerpt, &()); self.buffers .entry(props.buffer.id()) @@ -759,8 +741,6 @@ impl MultiBuffer { buffer_state.buffer.id(), buffer.snapshot(), old_excerpt.range.clone(), - old_excerpt.header_height, - old_excerpt.render_header.clone(), old_excerpt.has_trailing_newline, ); } else { @@ -821,35 +801,6 @@ impl MultiBufferSnapshot { .collect() } - pub fn excerpt_headers_in_range<'a>( - &'a self, - range: Range, - ) -> impl 'a + Iterator { - let mut cursor = self.excerpts.cursor::(); - cursor.seek(&Point::new(range.start, 0), Bias::Right, &()); - - if cursor.item().is_some() && range.start > cursor.start().row { - cursor.next(&()); - } - - iter::from_fn(move || { - while let Some(excerpt) = cursor.item() { - if cursor.start().row >= range.end { - break; - } - - if let Some(render) = excerpt.render_header.clone() { - let start = cursor.start().row; - cursor.next(&()); - return Some((start, excerpt.header_height, render)); - } else { - cursor.next(&()); - } - } - None - }) - } - pub fn reversed_chars_at<'a, T: ToOffset>( &'a self, position: T, @@ -1610,8 +1561,6 @@ impl Excerpt { buffer_id: usize, buffer: BufferSnapshot, range: Range, - header_height: u8, - render_header: Option, has_trailing_newline: bool, ) -> Self { Excerpt { @@ -1620,8 +1569,6 @@ impl Excerpt { buffer_id, buffer, range, - header_height, - render_header, has_trailing_newline, } } @@ -1974,7 +1921,7 @@ impl ToPoint for Point { #[cfg(test)] mod tests { use super::*; - use gpui::{elements::Empty, Element, MutableAppContext}; + use gpui::MutableAppContext; use language::{Buffer, Rope}; use rand::prelude::*; use std::env; @@ -2020,8 +1967,6 @@ mod tests { ExcerptProperties { buffer: &buffer_1, range: Point::new(1, 2)..Point::new(2, 5), - header_height: 2, - render_header: Some(Arc::new(|_| Empty::new().named("header 1"))), }, cx, ); @@ -2037,8 +1982,6 @@ mod tests { ExcerptProperties { buffer: &buffer_1, range: Point::new(3, 3)..Point::new(4, 4), - header_height: 1, - render_header: Some(Arc::new(|_| Empty::new().named("header 2"))), }, cx, ); @@ -2046,8 +1989,6 @@ mod tests { ExcerptProperties { buffer: &buffer_2, range: Point::new(3, 1)..Point::new(3, 3), - header_height: 3, - render_header: Some(Arc::new(|_| Empty::new().named("header 3"))), }, cx, ); @@ -2084,49 +2025,6 @@ mod tests { assert_eq!(snapshot.buffer_rows(4).collect::>(), [Some(3)]); assert_eq!(snapshot.buffer_rows(5).collect::>(), []); - { - let snapshot = multibuffer.read(cx).read(cx); - assert_eq!( - snapshot - .excerpt_headers_in_range(0..snapshot.max_point().row + 1) - .map(|(start_row, header_height, render)| ( - start_row, - header_height, - render(cx).name().unwrap().to_string() - )) - .collect::>(), - &[ - (0, 2, "header 1".into()), - (2, 1, "header 2".into()), - (4, 3, "header 3".into()) - ] - ); - - assert_eq!( - snapshot - .excerpt_headers_in_range(1..4) - .map(|(start_row, header_height, render)| ( - start_row, - header_height, - render(cx).name().unwrap().to_string() - )) - .collect::>(), - &[(2, 1, "header 2".into())] - ); - - assert_eq!( - snapshot - .excerpt_headers_in_range(2..5) - .map(|(start_row, header_height, render)| ( - start_row, - header_height, - render(cx).name().unwrap().to_string() - )) - .collect::>(), - &[(2, 1, "header 2".into()), (4, 3, "header 3".into())] - ); - } - buffer_1.update(cx, |buffer, cx| { buffer.edit( [ @@ -2158,7 +2056,6 @@ mod tests { }] ); - // bbbb\nc\ncc\nddd\neeee\njj let multibuffer = multibuffer.read(cx).snapshot(cx); assert_eq!( multibuffer.clip_point(Point::new(0, 5), Bias::Left), @@ -2222,8 +2119,6 @@ mod tests { ExcerptProperties { buffer: &buffer_1, range: 0..4, - header_height: 1, - render_header: None, }, cx, ); @@ -2231,8 +2126,6 @@ mod tests { ExcerptProperties { buffer: &buffer_2, range: 0..5, - header_height: 1, - render_header: None, }, cx, ); @@ -2318,8 +2211,6 @@ mod tests { ExcerptProperties { buffer: &buffer_handle, range: start_ix..end_ix, - header_height, - render_header: None, }, cx, ) @@ -2588,8 +2479,6 @@ mod tests { ExcerptProperties { buffer: &buffer_1, range: 0..buffer_1.read(cx).len(), - header_height: 0, - render_header: None, }, cx, ); @@ -2597,8 +2486,6 @@ mod tests { ExcerptProperties { buffer: &buffer_2, range: 0..buffer_2.read(cx).len(), - header_height: 0, - render_header: None, }, cx, );