From 54b58bb3452bd493a2881623a01371705ff806f1 Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Sun, 14 Jun 2026 20:24:50 +0300 Subject: feat: mark zoomed tabs in tab bar --- src/ui/tabs.rs | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tabs.rs b/src/ui/tabs.rs index ce859432..0ce99b7b 100644 --- a/src/ui/tabs.rs +++ b/src/ui/tabs.rs @@ -22,7 +22,16 @@ pub(crate) struct TabBarView { } fn tab_width(tab: &crate::workspace::Tab) -> u16 { - (tab.display_name().chars().count() as u16 + 4).max(MIN_TAB_WIDTH) + (tab_chrome_label(tab).chars().count() as u16 + 4).max(MIN_TAB_WIDTH) +} + +fn tab_chrome_label(tab: &crate::workspace::Tab) -> String { + let name = tab.display_name(); + if tab.zoomed { + format!("{name} Z") + } else { + name + } } fn layout_tab_hit_areas(ws: &crate::workspace::Workspace, area: Rect, scroll: usize) -> Vec { @@ -324,7 +333,7 @@ pub(super) fn render_tab_bar(app: &AppState, frame: &mut Frame, area: Rect) { Style::default().fg(p.overlay1).bg(p.surface0) }; let width = rect.width as usize; - let name = tab.display_name(); + let name = tab_chrome_label(tab); let text = format!(" {:width$}", name, width = width.saturating_sub(1)); frame.render_widget(Paragraph::new(text).style(style), rect); } @@ -379,3 +388,55 @@ pub(super) fn render_tab_bar(app: &AppState, frame: &mut Frame, area: Rect) { } } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::app::state::AppState; + use crate::workspace::Workspace; + use ratatui::{backend::TestBackend, Terminal}; + + fn buffer_row_text(buffer: &ratatui::buffer::Buffer, area: Rect, row: u16) -> String { + (area.x..area.x + area.width) + .map(|x| buffer[(x, row)].symbol()) + .collect::() + .trim_end() + .to_string() + } + + #[test] + fn tab_bar_marks_zoomed_tabs_without_renaming_them() { + let mut app = AppState::test_new(); + let mut ws = Workspace::test_new("test"); + ws.tabs[0].zoomed = true; + let custom_tab = ws.test_add_tab(Some("test")); + ws.tabs[custom_tab].zoomed = true; + + app.workspaces = vec![ws]; + app.active = Some(0); + app.view.tab_bar_rect = Rect::new(0, 0, 30, 1); + let view = compute_tab_bar_view(&app.workspaces[0], app.view.tab_bar_rect, 0, true, false); + app.view.tab_hit_areas = view.tab_hit_areas; + + let backend = TestBackend::new(30, 1); + let mut terminal = Terminal::new(backend).unwrap(); + terminal + .draw(|frame| render_tab_bar(&app, frame, app.view.tab_bar_rect)) + .unwrap(); + + let row = buffer_row_text(terminal.backend().buffer(), app.view.tab_bar_rect, 0); + assert!(row.contains(" 1 Z"), "tab row: {row:?}"); + assert!(row.contains(" test Z"), "tab row: {row:?}"); + assert_eq!(app.workspaces[0].tabs[0].display_name(), "1"); + assert_eq!(app.workspaces[0].tabs[custom_tab].display_name(), "test"); + } + + #[test] + fn zoom_marker_counts_toward_tab_width() { + let mut ws = Workspace::test_new("test"); + ws.tabs[0].set_custom_name("abcdefgh".into()); + ws.tabs[0].zoomed = true; + + assert_eq!(tab_width(&ws.tabs[0]), 14); + } +} -- cgit v1.2.3