- 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 <noreply@anthropic.com>
69 lines
2.0 KiB
Rust
69 lines
2.0 KiB
Rust
use crate::config::JustifyMode;
|
|
use crate::format;
|
|
use crate::layout::ActiveSection;
|
|
|
|
/// Distribute extra space evenly across gaps between sections.
|
|
/// Center the separator core (e.g., `|` from ` | `) within each gap.
|
|
/// Remainder chars distributed left-to-right.
|
|
pub fn justify(
|
|
active: &[ActiveSection],
|
|
term_width: u16,
|
|
separator: &str,
|
|
_mode: JustifyMode,
|
|
color_enabled: bool,
|
|
) -> String {
|
|
let content_width: usize = active
|
|
.iter()
|
|
.map(|s| format::display_width(&s.output.raw))
|
|
.sum();
|
|
|
|
let num_gaps = active.len().saturating_sub(1);
|
|
if num_gaps == 0 {
|
|
return active
|
|
.first()
|
|
.map(|s| s.output.ansi.clone())
|
|
.unwrap_or_default();
|
|
}
|
|
|
|
let available = (term_width as usize).saturating_sub(content_width);
|
|
let gap_width = available / num_gaps;
|
|
let gap_remainder = available % num_gaps;
|
|
|
|
// Extract separator core (non-space chars, e.g. "|" from " | ")
|
|
let sep_core = separator.trim();
|
|
let sep_core_len = format::display_width(sep_core);
|
|
|
|
let mut output = String::new();
|
|
for (i, sec) in active.iter().enumerate() {
|
|
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);
|
|
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);
|
|
}
|
|
|
|
output
|
|
}
|
|
|
|
/// Center the separator core within a gap of `total` columns.
|
|
fn build_gap(core: &str, core_len: usize, total: usize) -> String {
|
|
if core.is_empty() || core_len == 0 {
|
|
return " ".repeat(total);
|
|
}
|
|
|
|
let pad_total = total.saturating_sub(core_len);
|
|
let pad_left = pad_total / 2;
|
|
let pad_right = pad_total - pad_left;
|
|
|
|
format!("{}{core}{}", " ".repeat(pad_left), " ".repeat(pad_right))
|
|
}
|