From d5796dc5eb364b17f028188f844d150604258832 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 12 Mar 2024 14:33:12 +0100 Subject: [PATCH] Show only prefix/suffix if there are more than 12 breadcrumbs (#9220) Fixes https://github.com/zed-industries/zed/issues/9079 This should fix the arena panic we were observing. I saw that breadcrumb rendering was on the stack trace for some of the panics, so my suspicion is that it's being caused by some people navigating into deeply nested files. Release Notes: - Fixed a panic that could occur when displaying too many breadcrumbs. ([#9079](https://github.com/zed-industries/zed/issues/9079)) --- crates/breadcrumbs/src/breadcrumbs.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/crates/breadcrumbs/src/breadcrumbs.rs b/crates/breadcrumbs/src/breadcrumbs.rs index ca07a205ac971ce5d7fd206704f7cce3b0ae7d70..25e1d0346c9404ebc979038f7f5f7af332f869cb 100644 --- a/crates/breadcrumbs/src/breadcrumbs.rs +++ b/crates/breadcrumbs/src/breadcrumbs.rs @@ -4,10 +4,11 @@ use gpui::{ ViewContext, }; use itertools::Itertools; +use std::cmp; use theme::ActiveTheme; use ui::{prelude::*, ButtonLike, ButtonStyle, Label, Tooltip}; use workspace::{ - item::{ItemEvent, ItemHandle}, + item::{BreadcrumbText, ItemEvent, ItemHandle}, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, }; @@ -31,14 +32,30 @@ impl EventEmitter for Breadcrumbs {} impl Render for Breadcrumbs { fn render(&mut self, cx: &mut ViewContext) -> impl IntoElement { + const MAX_SEGMENTS: usize = 12; let element = h_flex().text_ui(); let Some(active_item) = self.active_item.as_ref() else { return element; }; - let Some(segments) = active_item.breadcrumbs(cx.theme(), cx) else { + let Some(mut segments) = active_item.breadcrumbs(cx.theme(), cx) else { return element; }; + let prefix_end_ix = cmp::min(segments.len(), MAX_SEGMENTS / 2); + let suffix_start_ix = cmp::max( + prefix_end_ix, + segments.len().saturating_sub(MAX_SEGMENTS / 2), + ); + if suffix_start_ix > prefix_end_ix { + segments.splice( + prefix_end_ix..suffix_start_ix, + Some(BreadcrumbText { + text: "⋯".into(), + highlights: None, + }), + ); + } + let highlighted_segments = segments.into_iter().map(|segment| { let mut text_style = cx.text_style(); text_style.color = Color::Muted.color(cx);