aboutsummaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-06-14 20:24:50 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-06-14 20:25:23 +0300
commit54b58bb3452bd493a2881623a01371705ff806f1 (patch)
tree09cf1b921e6b0092e3b3164b5cee1b38290593e3 /src/ui
parentc1ca8038451f5350d1fb3cd3c38e363fac3ae66c (diff)
feat: mark zoomed tabs in tab bar
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/tabs.rs65
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);
+ }
+}