From 263b8f32654588bc0ca229361f7b7be30d72aed2 Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Mon, 30 Mar 2026 00:30:24 +0300 Subject: feat: show upstream status in workspace sidebar --- src/ui.rs | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'src/ui.rs') diff --git a/src/ui.rs b/src/ui.rs index 291a2e98..2b5b8a4a 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -410,7 +410,23 @@ fn render_workspace_list(app: &AppState, frame: &mut Frame, area: Rect, is_navig ); row_y += 1; } else if let Some(branch) = ws.branch() { - let max_branch_len = (area.width as usize).saturating_sub(5); + let upstream_label = ws.git_ahead_behind().and_then(|(ahead, behind)| { + let mut parts = Vec::new(); + if ahead > 0 { + parts.push((format!("↑{}", ahead), p.green)); + } + if behind > 0 { + parts.push((format!("↓{}", behind), p.red)); + } + (!parts.is_empty()).then_some(parts) + }); + let reserved = upstream_label + .as_ref() + .map(|parts| { + parts.iter().map(|(label, _)| label.len()).sum::() + parts.len() + }) + .unwrap_or(0); + let max_branch_len = (area.width as usize).saturating_sub(5 + reserved); let branch_display = if branch.len() > max_branch_len { format!("{}…", &branch[..max_branch_len.saturating_sub(1)]) } else { @@ -421,10 +437,20 @@ fn render_workspace_list(app: &AppState, frame: &mut Frame, area: Rect, is_navig } else { p.overlay0 }; - let line2 = Line::from(vec![ + let mut spans = vec![ Span::styled(" ", Style::default()), Span::styled(branch_display, Style::default().fg(branch_color)), - ]); + ]; + if let Some(parts) = upstream_label { + spans.push(Span::styled(" ", Style::default())); + for (idx, (label, color)) in parts.into_iter().enumerate() { + if idx > 0 { + spans.push(Span::styled(" ", Style::default())); + } + spans.push(Span::styled(label, Style::default().fg(color))); + } + } + let line2 = Line::from(spans); frame.render_widget( Paragraph::new(line2), Rect::new(area.x, row_y, area.width, 1), -- cgit v1.2.3