From 50bc2d989e8c717e6bbdbfa031e0e410991ddf48 Mon Sep 17 00:00:00 2001 From: Taylor Eernisse Date: Fri, 6 Feb 2026 14:52:23 -0500 Subject: [PATCH] fix: 3 bugs from peer code review - justify: gate DIM/RESET separator coloring on color_enabled param; previously leaked ANSI escapes when --color=never or NO_COLOR was set - vcs: apply branch name truncation per config (truncate.enabled, truncate.max, truncate.style) for both git and jj renderers; previously ignored truncate config causing long branch names to overflow and trigger unnecessary priority drops - flex: account for prefix/suffix overhead when computing context_bar flex expansion width; previously double-applied apply_formatting causing line to overshoot term_width when prefix/suffix configured Co-Authored-By: Claude Opus 4.6 --- src/layout/flex.rs | 17 +++++++++++++---- src/layout/justify.rs | 15 ++++++++++----- src/layout/mod.rs | 1 + src/section/vcs.rs | 15 ++++++++++++++- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/layout/flex.rs b/src/layout/flex.rs index 9aa538c..0d5682d 100644 --- a/src/layout/flex.rs +++ b/src/layout/flex.rs @@ -44,12 +44,14 @@ pub fn flex_expand(active: &mut [ActiveSection], ctx: &RenderContext, separator: ansi: padding, }; } else if active[idx].id == "context_bar" { - // Rebuild context_bar with wider bar_width + // Rebuild context_bar with wider bar_width. + // Account for prefix/suffix that apply_formatting will add, + // so the final width doesn't overshoot term_width. + let base = &ctx.config.sections.context_bar.base; + let fmt_overhead = formatting_overhead(base); let cur_bar_width = ctx.config.sections.context_bar.bar_width; - let new_bar_width = cur_bar_width + extra as u16; + let new_bar_width = cur_bar_width + extra.saturating_sub(fmt_overhead) as u16; if let Some(mut output) = section::context_bar::render_at_width(ctx, new_bar_width) { - // Re-apply formatting after flex rebuild - let base = &ctx.config.sections.context_bar.base; format::apply_formatting( &mut output.raw, &mut output.ansi, @@ -66,6 +68,13 @@ pub fn flex_expand(active: &mut [ActiveSection], ctx: &RenderContext, separator: } } +/// Calculate display width of prefix + suffix that apply_formatting will add. +fn formatting_overhead(base: &crate::config::SectionBase) -> usize { + let pfx = base.prefix.as_deref().map_or(0, format::display_width); + let sfx = base.suffix.as_deref().map_or(0, format::display_width); + pfx + sfx +} + fn line_width(active: &[ActiveSection], separator: &str) -> usize { let sep_w = format::display_width(separator); let mut total = 0; diff --git a/src/layout/justify.rs b/src/layout/justify.rs index 298204c..d2db855 100644 --- a/src/layout/justify.rs +++ b/src/layout/justify.rs @@ -10,6 +10,7 @@ pub fn justify( term_width: u16, separator: &str, _mode: JustifyMode, + color_enabled: bool, ) -> String { let content_width: usize = active .iter() @@ -37,11 +38,15 @@ pub fn justify( if i > 0 { let this_gap = gap_width + usize::from(i - 1 < gap_remainder); let gap_str = build_gap(sep_core, sep_core_len, this_gap); - output.push_str(&format!( - "{}{gap_str}{}", - crate::color::DIM, - crate::color::RESET - )); + if color_enabled { + output.push_str(&format!( + "{}{gap_str}{}", + crate::color::DIM, + crate::color::RESET + )); + } else { + output.push_str(&gap_str); + } } output.push_str(&sec.output.ansi); } diff --git a/src/layout/mod.rs b/src/layout/mod.rs index c9efd5c..b40d2a0 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -109,6 +109,7 @@ fn render_line(section_ids: &[String], ctx: &RenderContext, separator: &str) -> ctx.term_width, separator, ctx.config.global.justify, + ctx.color_enabled, ) } else { flex::flex_expand(&mut active, ctx, separator); diff --git a/src/section/vcs.rs b/src/section/vcs.rs index f4eb13a..f3bab04 100644 --- a/src/section/vcs.rs +++ b/src/section/vcs.rs @@ -82,7 +82,13 @@ fn render_git( } }; - let branch = status.branch.as_deref().unwrap_or("?"); + let branch_raw = status.branch.as_deref().unwrap_or("?"); + let trunc = &ctx.config.sections.vcs.truncate; + let branch = if trunc.enabled && trunc.max > 0 { + crate::format::truncate(branch_raw, trunc.max, &trunc.style) + } else { + branch_raw.to_string() + }; let branch_glyph = glyph::glyph("branch", glyphs); let dirty_glyph = if status.is_dirty && ctx.config.sections.vcs.show_dirty { glyph::glyph("dirty", glyphs) @@ -154,6 +160,13 @@ fn render_jj( Some(out) })?; + let trunc = &ctx.config.sections.vcs.truncate; + let branch = if trunc.enabled && trunc.max > 0 { + crate::format::truncate(&branch, trunc.max, &trunc.style) + } else { + branch + }; + let branch_glyph = glyph::glyph("branch", glyphs); let raw = format!("{branch_glyph}{branch}"); let ansi = if ctx.color_enabled {