From 60fa3bc1c8f92cf08cf3dfa1ea9917581efb0991 Mon Sep 17 00:00:00 2001 From: "gcp-cherry-pick-bot[bot]" <98988430+gcp-cherry-pick-bot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 10:22:55 -0600 Subject: [PATCH] Show only prefix/suffix if there are more than 12 breadcrumbs (cherry-pick #9220) (#9227) Cherry-picked 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)) Co-authored-by: Antonio Scandurra --- 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);