From 3ee1c903e27cddafefdbb1db3aba387828181e01 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sat, 19 Oct 2024 22:21:49 -0400 Subject: [PATCH] WIP Co-authored-by: Antonio --- crates/assistant/src/assistant_panel.rs | 29 +- crates/editor/src/display_map.rs | 3 +- crates/editor/src/display_map/block_map.rs | 338 +++++++++++++-------- crates/editor/src/editor.rs | 10 +- crates/editor/src/editor_tests.rs | 5 +- crates/editor/src/element.rs | 9 +- crates/editor/src/hunk_diff.rs | 12 +- crates/repl/src/session.rs | 5 +- 8 files changed, 253 insertions(+), 158 deletions(-) diff --git a/crates/assistant/src/assistant_panel.rs b/crates/assistant/src/assistant_panel.rs index dea0cd8596..5c7f6af54f 100644 --- a/crates/assistant/src/assistant_panel.rs +++ b/crates/assistant/src/assistant_panel.rs @@ -2007,13 +2007,14 @@ impl ContextEditor { }) .map(|(command, error_message)| BlockProperties { style: BlockStyle::Fixed, - position: Anchor { - buffer_id: Some(buffer_id), - excerpt_id, - text_anchor: command.source_range.start, + placement: BlockPlacement::Below { + position: Anchor { + buffer_id: Some(buffer_id), + excerpt_id, + text_anchor: command.source_range.start, + }, }, height: 1, - disposition: BlockDisposition::Below, render: slash_command_error_block_renderer(error_message), priority: 0, }), @@ -2240,11 +2241,12 @@ impl ContextEditor { } else { let block_ids = editor.insert_blocks( [BlockProperties { - position: patch_start, + placement: BlockLinePlacement::Below { + position: patch_start, + }, height: path_count as u32 + 1, style: BlockStyle::Flex, render: render_block, - disposition: BlockDisposition::Below, priority: 0, }], None, @@ -2729,12 +2731,13 @@ impl ContextEditor { }) }; let create_block_properties = |message: &Message| BlockProperties { - position: buffer - .anchor_in_excerpt(excerpt_id, message.anchor_range.start) - .unwrap(), + placement: BlockLinePlacement::Above { + position: buffer + .anchor_in_excerpt(excerpt_id, message.anchor_range.start) + .unwrap(), + }, height: 2, style: BlockStyle::Sticky, - disposition: BlockDisposition::Above, priority: usize::MAX, render: render_block(MessageMetadata::from(message)), }; @@ -3370,7 +3373,7 @@ impl ContextEditor { let anchor = buffer.anchor_in_excerpt(excerpt_id, anchor).unwrap(); let image = render_image.clone(); anchor.is_valid(&buffer).then(|| BlockProperties { - position: anchor, + placement: BlockLinePlacement::Above { position: anchor }, height: MAX_HEIGHT_IN_LINES, style: BlockStyle::Sticky, render: Box::new(move |cx| { @@ -3391,8 +3394,6 @@ impl ContextEditor { ) .into_any_element() }), - - disposition: BlockDisposition::Above, priority: 0, }) }) diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index 790a0a6a1e..b8328d659e 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -29,7 +29,8 @@ use crate::{ }; pub use block_map::{ Block, BlockBufferRows, BlockChunks as DisplayChunks, BlockContext, BlockDisposition, BlockId, - BlockMap, BlockPoint, BlockProperties, BlockStyle, CustomBlockId, RenderBlock, + BlockLinePlacement, BlockMap, BlockPoint, BlockProperties, BlockStyle, CustomBlockId, + RenderBlock, }; use block_map::{BlockRow, BlockSnapshot}; use collections::{HashMap, HashSet}; diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index f4ee57408b..dc6c6198a7 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -6,7 +6,7 @@ use crate::{EditorStyle, GutterDimensions}; use collections::{Bound, HashMap, HashSet}; use gpui::{AnyElement, EntityId, Pixels, WindowContext}; use language::{Chunk, Patch, Point}; -use multi_buffer::{Anchor, ExcerptId, ExcerptInfo, MultiBufferRow, ToPoint as _}; +use multi_buffer::{Anchor, AnchorRangeExt, ExcerptId, MultiBufferRow, MultiBufferSnapshot}; use parking_lot::Mutex; use std::{ cell::RefCell, @@ -79,30 +79,101 @@ pub type RenderBlock = Box AnyElement>; pub struct CustomBlock { id: CustomBlockId, - position: Anchor, + placement: BlockLinePlacement, height: u32, style: BlockStyle, render: Arc>, - disposition: BlockDisposition, priority: usize, } +#[derive(Clone, Debug)] +pub enum BlockLinePlacement { + Above { position: T }, + Below { position: T }, + Replace { range: Range }, +} + +impl BlockLinePlacement { + fn cmp(&self, other: &Self, buffer: &MultiBufferSnapshot) -> Ordering { + fn cmp_between_replace( + (position, disposition): (&Anchor, &BlockDisposition), + range: &Range, + buffer: &MultiBufferSnapshot, + ) -> Ordering { + let start_cmp = position.cmp(&range.start, buffer); + if start_cmp.is_lt() { + Ordering::Less + } else if start_cmp.is_eq() { + if disposition.is_below() { + Ordering::Greater + } else { + Ordering::Less + } + } else { + let end_cmp = position.cmp(&range.end, buffer); + if end_cmp.is_gt() { + Ordering::Greater + } else if end_cmp.is_eq() { + if disposition.is_below() { + Ordering::Greater + } else { + Ordering::Less + } + } else { + Ordering::Greater + } + } + } + + match (self, other) { + ( + BlockLinePlacement::Between { + position: position_a, + disposition: disposition_a, + }, + BlockLinePlacement::Between { + position: position_b, + disposition: disposition_b, + }, + ) => position_a + .cmp(position_b, buffer) + .then_with(|| disposition_a.cmp(disposition_b)), + ( + BlockLinePlacement::Between { + position, + disposition, + }, + BlockLinePlacement::Replace { range }, + ) => cmp_between_replace((position, disposition), range, buffer), + ( + BlockLinePlacement::Replace { range }, + BlockLinePlacement::Between { + position, + disposition, + }, + ) => cmp_between_replace((position, disposition), range, buffer).reverse(), + ( + BlockLinePlacement::Replace { range: range_a }, + BlockLinePlacement::Replace { range: range_b }, + ) => range_a.cmp(range_b, buffer), + } + } +} + pub struct BlockProperties

{ - pub position: P, + pub placement: BlockLinePlacement

, pub height: u32, pub style: BlockStyle, pub render: RenderBlock, - pub disposition: BlockDisposition, pub priority: usize, } impl Debug for BlockProperties

{ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("BlockProperties") - .field("position", &self.position) + .field("placement", &self.placement) .field("height", &self.height) .field("style", &self.style) - .field("disposition", &self.disposition) .finish() } } @@ -172,7 +243,7 @@ pub(crate) enum BlockType { pub(crate) trait BlockLike { fn block_type(&self) -> BlockType; - fn disposition(&self) -> BlockDisposition; + fn placement(&self) -> &BlockLinePlacement; fn priority(&self) -> usize; } @@ -197,10 +268,6 @@ impl BlockLike for Block { } } - fn disposition(&self) -> BlockDisposition { - self.disposition() - } - fn priority(&self) -> usize { match self { Block::Custom(block) => block.priority, @@ -219,19 +286,6 @@ impl Block { } } - fn disposition(&self) -> BlockDisposition { - match self { - Block::Custom(block) => block.disposition, - Block::ExcerptBoundary { next_excerpt, .. } => { - if next_excerpt.is_some() { - BlockDisposition::Above - } else { - BlockDisposition::Below - } - } - } - } - pub fn height(&self) -> u32 { match self { Block::Custom(block) => block.height, @@ -245,6 +299,17 @@ impl Block { Block::ExcerptBoundary { .. } => BlockStyle::Sticky, } } + + fn place_below_line(&self) -> bool { + match self { + Block::Custom(block) => match &block.placement { + BlockLinePlacement::Between { disposition, .. } => disposition.is_below(), + BlockLinePlacement::Replace { .. } => false, + }, + Block::ExcerptHeader { .. } => false, + Block::ExcerptFooter { disposition, .. } => disposition.is_below(), + } + } } impl Debug for Block { @@ -377,18 +442,18 @@ impl BlockMap { while let Some(edit) = edits.next() { // Preserve any old transforms that precede this edit. - let old_start = WrapRow(edit.old.start); - let new_start = WrapRow(edit.new.start); + let mut old_start = WrapRow(edit.old.start); + let mut new_start = WrapRow(edit.new.start); new_transforms.append(cursor.slice(&old_start, Bias::Left, &()), &()); if let Some(transform) = cursor.item() { - if transform.is_isomorphic() && old_start == cursor.end(&()) { + if transform.summary.input_rows > 0 && old_start == cursor.end(&()) { new_transforms.push(transform.clone(), &()); cursor.next(&()); while let Some(transform) = cursor.item() { if transform .block .as_ref() - .map_or(false, |b| b.disposition().is_below()) + .map_or(false, |b| b.place_below_line()) { new_transforms.push(transform.clone(), &()); cursor.next(&()); @@ -399,9 +464,25 @@ impl BlockMap { } } - // Preserve any portion of an old transform that precedes this edit. - let extent_before_edit = old_start.0 - cursor.start().0; - push_isomorphic(&mut new_transforms, extent_before_edit); + let mut skip_blocks_above_start = false; + let transform = cursor.item().unwrap(); + let rows_before_edits = old_start.0 - cursor.start().0; + if rows_before_edits > 0 { + if transform.block.is_none() { + // Preserve any portion of the old isomorphic transform that precedes this edit. + push_isomorphic(&mut new_transforms, rows_before_edits); + } else { + // We landed within a block that replaces some lines, so we + // extend the edit to start at the beginning of the + // replacement. + debug_assert!(transform.summary.input_rows > 0); + old_start.0 -= rows_before_edits; + new_start.0 -= rows_before_edits; + // The blocks *above* it are already in the new transforms, so + // we don't need to re-insert them when querying blocks. + skip_blocks_above_start = true; + } + } // Skip over any old transforms that intersect this edit. let mut old_end = WrapRow(edit.old.end); @@ -413,7 +494,7 @@ impl BlockMap { if transform .block .as_ref() - .map_or(false, |b| b.disposition().is_below()) + .map_or(false, |b| b.place_below_line()) { cursor.next(&()); } else { @@ -434,7 +515,7 @@ impl BlockMap { if transform .block .as_ref() - .map_or(false, |b| b.disposition().is_below()) + .map_or(false, |b| b.place_below_line()) { cursor.next(&()); } else { @@ -631,14 +712,12 @@ impl BlockMap { }) } - pub(crate) fn sort_blocks(blocks: &mut [(u32, B)]) { + pub(crate) fn sort_blocks(blocks: &mut [(u32, B)]) { // Place excerpt headers and footers above custom blocks on the same row blocks.sort_unstable_by(|(row_a, block_a), (row_b, block_b)| { row_a.cmp(row_b).then_with(|| { - block_a - .disposition() - .cmp(&block_b.disposition()) - .then_with(|| match ((block_a.block_type()), (block_b.block_type())) { + block_a.placement().cmp(&block_b.placement()).then_with(|| { + match ((block_a.block_type()), (block_b.block_type())) { (BlockType::ExcerptBoundary, BlockType::ExcerptBoundary) => Ordering::Equal, (BlockType::ExcerptBoundary, _) => Ordering::Less, (_, BlockType::ExcerptBoundary) => Ordering::Greater, @@ -646,7 +725,8 @@ impl BlockMap { .priority() .cmp(&block_a.priority()) .then_with(|| a_id.cmp(&b_id)), - }) + } + }) }) }); } @@ -710,10 +790,11 @@ impl<'a> DerefMut for BlockMapReader<'a> { impl<'a> BlockMapReader<'a> { pub fn row_for_block(&self, block_id: CustomBlockId) -> Option { let block = self.blocks.iter().find(|block| block.id == block_id)?; - let buffer_row = block - .position - .to_point(self.wrap_snapshot.buffer_snapshot()) - .row; + let position = match &block.placement { + BlockLinePlacement::Between { position, .. } => *position, + BlockLinePlacement::Replace { range } => range.start, + }; + let buffer_row = position.to_point(self.wrap_snapshot.buffer_snapshot()).row; let wrap_row = self .wrap_snapshot .make_wrap_point(Point::new(buffer_row, 0), Bias::Left) @@ -765,36 +846,41 @@ impl<'a> BlockMapWriter<'a> { let id = CustomBlockId(self.0.next_block_id.fetch_add(1, SeqCst)); ids.push(id); - let position = block.position; - let point = position.to_point(buffer); - let wrap_row = wrap_snapshot - .make_wrap_point(Point::new(point.row, 0), Bias::Left) - .row(); - - let (start_row, end_row) = { - previous_wrap_row_range.take_if(|range| !range.contains(&wrap_row)); - let range = previous_wrap_row_range.get_or_insert_with(|| { - let start_row = wrap_snapshot.prev_row_boundary(WrapPoint::new(wrap_row, 0)); - let end_row = wrap_snapshot - .next_row_boundary(WrapPoint::new(wrap_row, 0)) - .unwrap_or(wrap_snapshot.max_point().row() + 1); - start_row..end_row - }); - (range.start, range.end) + let range = match &block.placement { + BlockLinePlacement::Between { position, .. } => *position..*position, + BlockLinePlacement::Replace { range } => range.clone(), }; + let start_point = range.start.to_point(buffer); + let start_wrap_row = wrap_snapshot + .make_wrap_point(Point::new(start_point.row, 0), Bias::Left) + .row(); + let end_point = range.end.to_point(buffer); + let end_wrap_row = wrap_snapshot + .make_wrap_point(Point::new(end_point.row, 0), Bias::Right) + .row(); + previous_wrap_row_range.take_if(|range| { + !range.contains(&start_wrap_row) || !range.contains(&end_wrap_row) + }); + let wrap_row_range = previous_wrap_row_range.get_or_insert_with(|| { + let start_row = wrap_snapshot.prev_row_boundary(WrapPoint::new(start_wrap_row, 0)); + let end_row = wrap_snapshot + .next_row_boundary(WrapPoint::new(end_wrap_row, 0)) + .unwrap_or(wrap_snapshot.max_point().row() + 1); + start_row..end_row + }); + let block_ix = match self .0 .custom_blocks - .binary_search_by(|probe| probe.position.cmp(&position, buffer)) + .binary_search_by(|probe| probe.placement.cmp(&block.placement, buffer)) { Ok(ix) | Err(ix) => ix, }; let new_block = Arc::new(CustomBlock { id, - position, + placement: block.placement, height: block.height, render: Arc::new(Mutex::new(block.render)), - disposition: block.disposition, style: block.style, priority: block.priority, }); @@ -802,8 +888,8 @@ impl<'a> BlockMapWriter<'a> { self.0.custom_blocks_by_id.insert(id, new_block); edits = edits.compose([Edit { - old: start_row..end_row, - new: start_row..end_row, + old: wrap_row_range.clone(), + new: wrap_row_range.clone(), }]); } @@ -815,38 +901,47 @@ impl<'a> BlockMapWriter<'a> { let wrap_snapshot = &*self.0.wrap_snapshot.borrow(); let buffer = wrap_snapshot.buffer_snapshot(); let mut edits = Patch::default(); - let mut last_block_buffer_row = None; + let mut last_block_end_buffer_row = None; for block in &mut self.0.custom_blocks { if let Some(new_height) = heights.remove(&block.id) { if block.height != new_height { let new_block = CustomBlock { id: block.id, - position: block.position, + placement: block.placement, height: new_height, style: block.style, render: block.render.clone(), - disposition: block.disposition, priority: block.priority, }; let new_block = Arc::new(new_block); *block = new_block.clone(); self.0.custom_blocks_by_id.insert(block.id, new_block); - let buffer_row = block.position.to_point(buffer).row; - if last_block_buffer_row != Some(buffer_row) { - last_block_buffer_row = Some(buffer_row); - let wrap_row = wrap_snapshot - .make_wrap_point(Point::new(buffer_row, 0), Bias::Left) + let range = match &block.placement { + BlockLinePlacement::Between { position, .. } => *position..*position, + BlockLinePlacement::Replace { range } => range.clone(), + }; + + let end_buffer_row = range.end.to_point(buffer).row; + if last_block_end_buffer_row != Some(end_buffer_row) { + last_block_end_buffer_row = Some(end_buffer_row); + let start_buffer_row = range.start.to_point(buffer).row; + let mut start_wrap_row = wrap_snapshot + .make_wrap_point(Point::new(start_buffer_row, 0), Bias::Left) .row(); - let start_row = - wrap_snapshot.prev_row_boundary(WrapPoint::new(wrap_row, 0)); - let end_row = wrap_snapshot - .next_row_boundary(WrapPoint::new(wrap_row, 0)) + start_wrap_row = + wrap_snapshot.prev_row_boundary(WrapPoint::new(start_wrap_row, 0)); + + let mut end_wrap_row = wrap_snapshot + .make_wrap_point(Point::new(end_buffer_row, 0), Bias::Right) + .row(); + end_wrap_row = wrap_snapshot + .next_row_boundary(WrapPoint::new(end_wrap_row, 0)) .unwrap_or(wrap_snapshot.max_point().row() + 1); edits.push(Edit { - old: start_row..end_row, - new: start_row..end_row, + old: start_wrap_row..end_wrap_row, + new: start_wrap_row..end_wrap_row, }) } } @@ -1186,10 +1281,6 @@ impl Transform { block: Some(block), } } - - fn is_isomorphic(&self) -> bool { - self.block.is_none() - } } impl<'a> BlockChunks<'a> { @@ -1380,10 +1471,6 @@ impl CustomBlock { self.render.lock()(cx) } - pub fn position(&self) -> &Anchor { - &self.position - } - pub fn style(&self) -> BlockStyle { self.style } @@ -1393,8 +1480,7 @@ impl Debug for CustomBlock { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("Block") .field("id", &self.id) - .field("position", &self.position) - .field("disposition", &self.disposition) + .field("placement", &self.placement) .finish() } } @@ -1465,25 +1551,31 @@ mod tests { let block_ids = writer.insert(vec![ BlockProperties { style: BlockStyle::Fixed, - position: buffer_snapshot.anchor_after(Point::new(1, 0)), + placement: BlockLinePlacement::Between { + position: buffer_snapshot.anchor_after(Point::new(1, 0)), + disposition: BlockDisposition::Above, + }, height: 1, - disposition: BlockDisposition::Above, render: Box::new(|_| div().into_any()), priority: 0, }, BlockProperties { style: BlockStyle::Fixed, - position: buffer_snapshot.anchor_after(Point::new(1, 2)), + placement: BlockLinePlacement::Between { + position: buffer_snapshot.anchor_after(Point::new(1, 2)), + disposition: BlockDisposition::Above, + }, height: 2, - disposition: BlockDisposition::Above, render: Box::new(|_| div().into_any()), priority: 0, }, BlockProperties { style: BlockStyle::Fixed, - position: buffer_snapshot.anchor_after(Point::new(3, 3)), + placement: BlockLinePlacement::Between { + position: buffer_snapshot.anchor_after(Point::new(3, 3)), + disposition: BlockDisposition::Below, + }, height: 3, - disposition: BlockDisposition::Below, render: Box::new(|_| div().into_any()), priority: 0, }, @@ -1719,25 +1811,31 @@ mod tests { let block_ids = writer.insert(vec![ BlockProperties { style: BlockStyle::Fixed, - position: buffer_snapshot.anchor_after(Point::new(1, 0)), + placement: BlockLinePlacement::Between { + position: buffer_snapshot.anchor_after(Point::new(1, 0)), + disposition: BlockDisposition::Above, + }, height: 1, - disposition: BlockDisposition::Above, render: Box::new(|_| div().into_any()), priority: 0, }, BlockProperties { style: BlockStyle::Fixed, - position: buffer_snapshot.anchor_after(Point::new(1, 2)), + placement: BlockLinePlacement::Between { + position: buffer_snapshot.anchor_after(Point::new(1, 2)), + disposition: BlockDisposition::Above, + }, height: 2, - disposition: BlockDisposition::Above, render: Box::new(|_| div().into_any()), priority: 0, }, BlockProperties { style: BlockStyle::Fixed, - position: buffer_snapshot.anchor_after(Point::new(3, 3)), + placement: BlockLinePlacement::Between { + position: buffer_snapshot.anchor_after(Point::new(3, 3)), + disposition: BlockDisposition::Below, + }, height: 3, - disposition: BlockDisposition::Below, render: Box::new(|_| div().into_any()), priority: 0, }, @@ -1825,16 +1923,20 @@ mod tests { writer.insert(vec![ BlockProperties { style: BlockStyle::Fixed, - position: buffer_snapshot.anchor_after(Point::new(1, 12)), - disposition: BlockDisposition::Above, + placement: BlockLinePlacement::Between { + position: buffer_snapshot.anchor_after(Point::new(1, 12)), + disposition: BlockDisposition::Above, + }, render: Box::new(|_| div().into_any()), height: 1, priority: 0, }, BlockProperties { style: BlockStyle::Fixed, - position: buffer_snapshot.anchor_after(Point::new(1, 1)), - disposition: BlockDisposition::Below, + placement: BlockLinePlacement::Between { + position: buffer_snapshot.anchor_after(Point::new(1, 1)), + disposition: BlockDisposition::Below, + }, render: Box::new(|_| div().into_any()), height: 1, priority: 0, @@ -1931,10 +2033,12 @@ mod tests { height ); BlockProperties { + placement: BlockLinePlacement::Between { + position, + disposition, + }, style: BlockStyle::Fixed, - position, height, - disposition, render: Box::new(|_| div().into_any()), priority: 0, } @@ -1952,11 +2056,10 @@ mod tests { let mut block_map = block_map.write(wraps_snapshot, wrap_edits); let block_ids = block_map.insert(block_properties.iter().map(|props| BlockProperties { - position: props.position, + placement: props.placement, height: props.height, style: props.style, render: Box::new(|_| div().into_any()), - disposition: props.disposition, priority: 0, })); for (block_id, props) in block_ids.into_iter().zip(block_properties) { @@ -2259,10 +2362,6 @@ mod tests { } } - fn disposition(&self) -> BlockDisposition { - self.disposition() - } - fn priority(&self) -> usize { match self { ExpectedBlock::Custom { priority, .. } => *priority, @@ -2278,19 +2377,6 @@ mod tests { ExpectedBlock::Custom { height, .. } => *height, } } - - fn disposition(&self) -> BlockDisposition { - match self { - ExpectedBlock::ExcerptBoundary { is_last, .. } => { - if *is_last { - BlockDisposition::Below - } else { - BlockDisposition::Above - } - } - ExpectedBlock::Custom { disposition, .. } => *disposition, - } - } } impl From for ExpectedBlock { diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index f7fef4707c..2e1b133e2b 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -10227,7 +10227,9 @@ impl Editor { let block_id = this.insert_blocks( [BlockProperties { style: BlockStyle::Flex, - position: range.start, + placement: BlockLinePlacement::Below { + position: range.start, + }, height: 1, render: Box::new({ let rename_editor = rename_editor.clone(); @@ -10263,7 +10265,6 @@ impl Editor { .into_any_element() } }), - disposition: BlockDisposition::Below, priority: 0, }], Some(Autoscroll::fit()), @@ -10548,10 +10549,11 @@ impl Editor { let message_height = diagnostic.message.matches('\n').count() as u32 + 1; BlockProperties { style: BlockStyle::Fixed, - position: buffer.anchor_after(entry.range.start), + placement: BlockLinePlacement::Below { + position: buffer.anchor_after(entry.range.start), + }, height: message_height, render: diagnostic_block_renderer(diagnostic, None, true, true), - disposition: BlockDisposition::Below, priority: 0, } }), diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index fdcfaab82f..a0ccf45a8b 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -3868,8 +3868,9 @@ fn test_move_line_up_down_with_blocks(cx: &mut TestAppContext) { editor.insert_blocks( [BlockProperties { style: BlockStyle::Fixed, - position: snapshot.anchor_after(Point::new(2, 0)), - disposition: BlockDisposition::Below, + placement: BlockLinePlacement::Below { + position: snapshot.anchor_after(Point::new(2, 0)), + }, height: 1, render: Box::new(|_| div().into_any()), priority: 0, diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 77b78d059c..a61b73fbcb 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -6295,9 +6295,9 @@ fn compute_auto_height_layout( mod tests { use super::*; use crate::{ - display_map::{BlockDisposition, BlockProperties}, + display_map::BlockProperties, editor_tests::{init_test, update_test_language_settings}, - Editor, MultiBuffer, + BlockLinePlacement, Editor, MultiBuffer, }; use gpui::{TestAppContext, VisualTestContext}; use language::language_settings; @@ -6551,9 +6551,10 @@ mod tests { editor.insert_blocks( [BlockProperties { style: BlockStyle::Fixed, - disposition: BlockDisposition::Above, + placement: BlockLinePlacement::Above { + position: Anchor::min(), + }, height: 3, - position: Anchor::min(), render: Box::new(|cx| div().h(3. * cx.line_height()).into_any()), priority: 0, }], diff --git a/crates/editor/src/hunk_diff.rs b/crates/editor/src/hunk_diff.rs index c3a539b3d4..d34327cfc4 100644 --- a/crates/editor/src/hunk_diff.rs +++ b/crates/editor/src/hunk_diff.rs @@ -15,7 +15,7 @@ use util::RangeExt; use crate::{ editor_settings::CurrentLineHighlight, hunk_status, hunks_for_selections, ApplyDiffHunk, - BlockDisposition, BlockProperties, BlockStyle, CustomBlockId, DiffRowHighlight, DisplayRow, + BlockLinePlacement, BlockProperties, BlockStyle, CustomBlockId, DiffRowHighlight, DisplayRow, DisplaySnapshot, Editor, EditorElement, ExpandAllHunkDiffs, GoToHunk, GoToPrevHunk, RevertFile, RevertSelectedHunks, ToDisplayPoint, ToggleHunkDiff, }; @@ -377,10 +377,11 @@ impl Editor { }; BlockProperties { - position: hunk.multi_buffer_range.start, + placement: BlockLinePlacement::Above { + position: hunk.multi_buffer_range.start, + }, height: 1, style: BlockStyle::Sticky, - disposition: BlockDisposition::Above, priority: 0, render: Box::new({ let editor = cx.view().clone(); @@ -659,10 +660,11 @@ impl Editor { let hunk = hunk.clone(); let height = editor_height.max(deleted_text_height); BlockProperties { - position: hunk.multi_buffer_range.start, + placement: BlockLinePlacement::Above { + position: hunk.multi_buffer_range.start, + }, height, style: BlockStyle::Flex, - disposition: BlockDisposition::Above, priority: 0, render: Box::new(move |cx| { let width = EditorElement::diff_hunk_strip_width(cx.line_height()); diff --git a/crates/repl/src/session.rs b/crates/repl/src/session.rs index 7f312023c3..0ba46bfede 100644 --- a/crates/repl/src/session.rs +++ b/crates/repl/src/session.rs @@ -90,12 +90,13 @@ impl EditorBlock { let invalidation_anchor = buffer.read(cx).read(cx).anchor_before(next_row_start); let block = BlockProperties { - position: code_range.end, + placement: BlockLinePlacement::Below { + position: code_range.end, + }, // Take up at least one height for status, allow the editor to determine the real height based on the content from render height: 1, style: BlockStyle::Sticky, render: Self::create_output_area_renderer(execution_view.clone(), on_close.clone()), - disposition: BlockDisposition::Below, priority: 0, };