claude_code_status_line/
render.rs

1use crate::colors::SectionColors;
2use crate::config::Config;
3use crate::types::Section;
4use crate::utils::RESET;
5
6/// Render sections using segmented style (either Powerline arrows or custom separator)
7pub fn render_segments(sections: &[&Section], config: &Config) -> String {
8    let mut result = String::new();
9
10    for (i, section) in sections.iter().enumerate() {
11        result.push_str(&render_section(&section.content, &section.colors, config));
12
13        if i < sections.len() - 1 {
14            let next = sections[i + 1];
15            if config.display.use_arrows {
16                let left_bg = section.colors.bg.unwrap_or((0, 0, 0));
17                let right_bg = next.colors.bg.unwrap_or((0, 0, 0));
18                result.push_str(&make_powerline_arrow(left_bg, right_bg, config));
19            } else if !config.display.separator.is_empty() {
20                result.push_str(&make_separator(config));
21            }
22        }
23    }
24
25    // Add tail arrow only if using arrows
26    if config.display.use_arrows {
27        if let Some(last) = sections.last() {
28            if let Some(bg) = last.colors.bg {
29                result.push_str(&format!(
30                    "\x1b[38;2;{};{};{}m\x1b[49m{}",
31                    bg.0, bg.1, bg.2, config.display.arrow
32                ));
33            }
34        }
35    }
36
37    result.push_str(RESET);
38    result
39}
40
41/// Render a single section with its colors (with padding)
42fn render_section(content: &str, colors: &SectionColors, config: &Config) -> String {
43    let bg_code = match colors.bg {
44        Some(bg) => format!("\x1b[48;2;{};{};{}m", bg.0, bg.1, bg.2),
45        None => "\x1b[49m".to_string(), // Reset background
46    };
47
48    let padding = " ".repeat(config.display.section_padding);
49
50    format!(
51        "{}\x1b[38;2;{};{};{}m{}{}{}",
52        bg_code, colors.fg.0, colors.fg.1, colors.fg.2, padding, content, padding
53    )
54}
55
56/// Generate powerline arrow between two sections
57fn make_powerline_arrow(left_bg: (u8, u8, u8), right_bg: (u8, u8, u8), config: &Config) -> String {
58    format!(
59        "\x1b[38;2;{};{};{}m\x1b[48;2;{};{};{}m{}",
60        left_bg.0, left_bg.1, left_bg.2, right_bg.0, right_bg.1, right_bg.2, config.display.arrow
61    )
62}
63
64/// Generate ANSI escape code for muted text using section's muted color
65fn make_muted_from_section(colors: &SectionColors) -> String {
66    format!(
67        "\x1b[38;2;{};{};{}m",
68        colors.muted.0, colors.muted.1, colors.muted.2
69    )
70}
71
72/// Generate ANSI escape code to restore foreground color for a section
73fn restore_fg_from_section(colors: &SectionColors) -> String {
74    format!("\x1b[38;2;{};{};{}m", colors.fg.0, colors.fg.1, colors.fg.2)
75}
76
77/// Helper to get muted and foreground color codes (unified logic)
78pub fn get_muted_and_fg_codes(colors: &SectionColors, _config: &Config) -> (String, String) {
79    (
80        make_muted_from_section(colors),
81        restore_fg_from_section(colors),
82    )
83}
84
85/// Generate separator string with reset colors
86fn make_separator(config: &Config) -> String {
87    let color = config.theme.separator;
88    format!(
89        "{}\x1b[38;2;{};{};{}m{}\x1b[0m",
90        RESET, color.0, color.1, color.2, config.display.separator
91    )
92}