breadcrumbs: Stylize filename in breadcrumbs when tab-bar is off and file is dirty (#30507)

Closes [#18870](https://github.com/zed-industries/zed/issues/18870)


- I like to use Zed with tab_bar off
- when the file is modified there is no indicator when tab_bar is off
- this PR aims to fix that

Thanks to @Qkessler for initial PR - #22418 

This is style decided in this discussion - #22418 
@iamnbutler @mikayla-maki [subtle style
decided](https://github.com/zed-industries/zed/pull/22418#issuecomment-2605253667)

Release Notes:
- When tab_bar is off, filename in the breadcrumbs will be the indicator
when file is unsaved.


#### Changes
- when tab_bar is off and file is dirty (unsaved)
<img width="834" alt="image"
src="https://github.com/user-attachments/assets/f205731b-c8e3-4d7a-9214-cbe706e372bf"
/>


- when tab_bar is off and file is not dirty (saved)
<img width="846" alt="image"
src="https://github.com/user-attachments/assets/88ea96eb-16a2-48e8-900d-64a921f0b5c3"
/>


- when tab_bar is on
<img width="741" alt="image"
src="https://github.com/user-attachments/assets/cc543544-9949-46ed-8e09-cdcbe2f47ab8"
/>

<img width="740" alt="image"
src="https://github.com/user-attachments/assets/8d347258-26f7-4bd7-82d4-8f23dbe63d61"
/>

Release Notes:

- Changed the highlighting of the current file to represent the current
saved state, when the tab bar is turned off.
This commit is contained in:
Vivek Pothina 2025-05-30 08:32:54 -07:00 committed by GitHub
parent 8bec4cbecb
commit 07436b4284
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 60 additions and 7 deletions

1
Cargo.lock generated
View file

@ -2200,6 +2200,7 @@ dependencies = [
"editor",
"gpui",
"itertools 0.14.0",
"settings",
"theme",
"ui",
"workspace",

View file

@ -16,6 +16,7 @@ doctest = false
editor.workspace = true
gpui.workspace = true
itertools.workspace = true
settings.workspace = true
theme.workspace = true
ui.workspace = true
workspace.workspace = true

View file

@ -1,14 +1,15 @@
use editor::Editor;
use gpui::{
Context, Element, EventEmitter, Focusable, IntoElement, ParentElement, Render, StyledText,
Subscription, Window,
Context, Element, EventEmitter, Focusable, FontWeight, IntoElement, ParentElement, Render,
StyledText, Subscription, Window,
};
use itertools::Itertools;
use settings::Settings;
use std::cmp;
use theme::ActiveTheme;
use ui::{ButtonLike, ButtonStyle, Label, Tooltip, prelude::*};
use workspace::{
ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView,
TabBarSettings, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView,
item::{BreadcrumbText, ItemEvent, ItemHandle},
};
@ -71,16 +72,23 @@ impl Render for Breadcrumbs {
);
}
let highlighted_segments = segments.into_iter().map(|segment| {
let highlighted_segments = segments.into_iter().enumerate().map(|(index, segment)| {
let mut text_style = window.text_style();
if let Some(font) = segment.font {
text_style.font_family = font.family;
text_style.font_features = font.features;
if let Some(ref font) = segment.font {
text_style.font_family = font.family.clone();
text_style.font_features = font.features.clone();
text_style.font_style = font.style;
text_style.font_weight = font.weight;
}
text_style.color = Color::Muted.color(cx);
if index == 0 && !TabBarSettings::get_global(cx).show && active_item.is_dirty(cx) {
if let Some(styled_element) = apply_dirty_filename_style(&segment, &text_style, cx)
{
return styled_element;
}
}
StyledText::new(segment.text.replace('\n', ""))
.with_default_highlights(&text_style, segment.highlights.unwrap_or_default())
.into_any()
@ -184,3 +192,46 @@ impl ToolbarItemView for Breadcrumbs {
self.pane_focused = pane_focused;
}
}
fn apply_dirty_filename_style(
segment: &BreadcrumbText,
text_style: &gpui::TextStyle,
cx: &mut Context<Breadcrumbs>,
) -> Option<gpui::AnyElement> {
let text = segment.text.replace('\n', "");
let filename_position = std::path::Path::new(&segment.text)
.file_name()
.and_then(|f| {
let filename_str = f.to_string_lossy();
segment.text.rfind(filename_str.as_ref())
})?;
let bold_weight = FontWeight::BOLD;
let default_color = Color::Default.color(cx);
if filename_position == 0 {
let mut filename_style = text_style.clone();
filename_style.font_weight = bold_weight;
filename_style.color = default_color;
return Some(
StyledText::new(text)
.with_default_highlights(&filename_style, [])
.into_any(),
);
}
let highlight_style = gpui::HighlightStyle {
font_weight: Some(bold_weight),
color: Some(default_color),
..Default::default()
};
let highlight = vec![(filename_position..text.len(), highlight_style)];
Some(
StyledText::new(text)
.with_default_highlights(&text_style, highlight)
.into_any(),
)
}