From 3b5dffea925da29f04e41b3ea5ce534adb45e71d Mon Sep 17 00:00:00 2001 From: "zed-zippy[bot]" <234243425+zed-zippy[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 10:49:45 -0500 Subject: [PATCH] editor: Add `FlexClipped` block style and use it for spacer blocks (#49478) (cherry-pick to preview) (#49492) Cherry-pick of #49478 to preview ---- `FlexClipped` acts like `Flex`, but only allows the block to render in the main hitbox, not the gutter. This is a visual improvement for the spacers compared to `Sticky`. https://github.com/user-attachments/assets/2b0aed0c-91ff-4e74-85b1-aea81f4e8a35 Release Notes: - git: Improved the visual display for spacers in the split diff view. Co-authored-by: Smit Barmase Co-authored-by: Cole Miller Co-authored-by: Smit Barmase --- crates/editor/src/display_map/block_map.rs | 9 ++++-- crates/editor/src/element.rs | 32 ++++++++++++++++++---- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index de9d94fdb94b08c05efb582f2f56d4b8078b1ead..9514cfd78299811423a774101a6ca8b4d04bd2a6 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -265,6 +265,8 @@ impl Debug for BlockProperties

{ pub enum BlockStyle { Fixed, Flex, + /// Like `Flex` but doesn't use the gutter + FlexClipped, Sticky, } @@ -272,6 +274,7 @@ pub enum BlockStyle { pub struct EditorMargins { pub gutter: GutterDimensions, pub right: Pixels, + pub extended_right: Pixels, } #[derive(gpui::AppContext, gpui::VisualContext)] @@ -393,8 +396,8 @@ impl Block { Block::Custom(block) => block.style, Block::ExcerptBoundary { .. } | Block::FoldedBuffer { .. } - | Block::BufferHeader { .. } - | Block::Spacer { .. } => BlockStyle::Sticky, + | Block::BufferHeader { .. } => BlockStyle::Sticky, + Block::Spacer { .. } => BlockStyle::FlexClipped, } } @@ -1707,7 +1710,7 @@ pub(crate) fn balancing_block( Some(BlockProperties { placement: their_placement, height: my_block.height, - style: BlockStyle::Sticky, + style: BlockStyle::FlexClipped, render: Arc::new(move |cx| { crate::EditorElement::render_spacer_block( cx.block_id, diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index d1fd99f09217dc736c12c3f8902fc2bdb777e03d..ea779890496827155b29aa4a8b7cdd9afef96672 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -4224,7 +4224,15 @@ impl EditorElement { .size .width .max(fixed_block_max_width) - .max(editor_margins.gutter.width + *scroll_width) + .max( + editor_margins.gutter.width + *scroll_width + editor_margins.extended_right, + ) + .into(), + (BlockStyle::FlexClipped, _) => hitbox + .size + .width + .max(fixed_block_max_width) + .max(*scroll_width + editor_margins.extended_right) .into(), (BlockStyle::Fixed, _) => unreachable!(), }; @@ -4267,7 +4275,7 @@ impl EditorElement { element, available_space: size(width, element_size.height.into()), style, - overlaps_gutter: !block.place_near(), + overlaps_gutter: !block.place_near() && style != BlockStyle::FlexClipped, is_buffer_header: block.is_buffer_header(), }); } @@ -4281,12 +4289,17 @@ impl EditorElement { let style = block.style(); let width = match style { BlockStyle::Fixed => AvailableSpace::MinContent, - BlockStyle::Flex => AvailableSpace::Definite( + BlockStyle::Flex => { + AvailableSpace::Definite(hitbox.size.width.max(fixed_block_max_width).max( + editor_margins.gutter.width + *scroll_width + editor_margins.extended_right, + )) + } + BlockStyle::FlexClipped => AvailableSpace::Definite( hitbox .size .width .max(fixed_block_max_width) - .max(editor_margins.gutter.width + *scroll_width), + .max(*scroll_width + editor_margins.extended_right), ), BlockStyle::Sticky => AvailableSpace::Definite(hitbox.size.width), }; @@ -4346,6 +4359,7 @@ impl EditorElement { &self, blocks: &mut Vec, hitbox: &Hitbox, + gutter_hitbox: &Hitbox, line_height: Pixels, scroll_position: gpui::Point, scroll_pixel_position: gpui::Point, @@ -4367,6 +4381,10 @@ impl EditorElement { hitbox.origin + point(Pixels::ZERO, hitbox.size.height) }; + if block.style == BlockStyle::FlexClipped { + origin += point(gutter_hitbox.size.width, Pixels::ZERO); + } + if !matches!(block.style, BlockStyle::Sticky) { origin += point(Pixels::from(-scroll_pixel_position.x), Pixels::ZERO); } @@ -9561,11 +9579,12 @@ impl Element for EditorElement { let right_margin = minimap_width + vertical_scrollbar_width; - let editor_width = - text_width - gutter_dimensions.margin - 2 * em_width - right_margin; + let extended_right = 2 * em_width + right_margin; + let editor_width = text_width - gutter_dimensions.margin - extended_right; let editor_margins = EditorMargins { gutter: gutter_dimensions, right: right_margin, + extended_right, }; snapshot = self.editor.update(cx, |editor, cx| { @@ -10449,6 +10468,7 @@ impl Element for EditorElement { self.layout_blocks( &mut blocks, &hitbox, + &gutter_hitbox, line_height, scroll_position, scroll_pixel_position,