diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-14 20:24:50 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-14 20:25:23 +0300 |
| commit | 54b58bb3452bd493a2881623a01371705ff806f1 (patch) | |
| tree | 09cf1b921e6b0092e3b3164b5cee1b38290593e3 /src | |
| parent | c1ca8038451f5350d1fb3cd3c38e363fac3ae66c (diff) | |
feat: mark zoomed tabs in tab bar
Diffstat (limited to 'src')
| -rw-r--r-- | src/ui/tabs.rs | 65 |
1 files changed, 63 insertions, 2 deletions
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<Rect> { @@ -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::<String>() + .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); + } +} |
