Port the entire 2236-line bash statusline script to Rust. Implements all 25 sections, 3-phase layout engine (render, priority drop, flex/justify), file-based caching with flock, 9-level terminal width detection, trend sparklines, and deep-merge JSON config. Release binary: 864K with LTO. Render time: <1ms warm. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
77 lines
2.1 KiB
Rust
77 lines
2.1 KiB
Rust
use crate::config::ThemeColors;
|
|
use crate::theme::Theme;
|
|
|
|
pub const RESET: &str = "\x1b[0m";
|
|
pub const BOLD: &str = "\x1b[1m";
|
|
pub const DIM: &str = "\x1b[2m";
|
|
pub const RED: &str = "\x1b[31m";
|
|
pub const GREEN: &str = "\x1b[32m";
|
|
pub const YELLOW: &str = "\x1b[33m";
|
|
pub const BLUE: &str = "\x1b[34m";
|
|
pub const MAGENTA: &str = "\x1b[35m";
|
|
pub const CYAN: &str = "\x1b[36m";
|
|
pub const WHITE: &str = "\x1b[37m";
|
|
|
|
/// Resolve a color name to ANSI escape sequence(s).
|
|
pub fn resolve_color(name: &str, theme: Theme, palette: &ThemeColors) -> String {
|
|
if let Some(key) = name.strip_prefix("p:") {
|
|
let map = match theme {
|
|
Theme::Dark => &palette.dark,
|
|
Theme::Light => &palette.light,
|
|
};
|
|
if let Some(resolved) = map.get(key) {
|
|
return resolve_color(resolved, theme, palette);
|
|
}
|
|
return RESET.to_string();
|
|
}
|
|
|
|
let mut result = String::new();
|
|
for part in name.split_whitespace() {
|
|
result.push_str(match part {
|
|
"red" => RED,
|
|
"green" => GREEN,
|
|
"yellow" => YELLOW,
|
|
"blue" => BLUE,
|
|
"magenta" => MAGENTA,
|
|
"cyan" => CYAN,
|
|
"white" => WHITE,
|
|
"dim" => DIM,
|
|
"bold" => BOLD,
|
|
_ => "",
|
|
});
|
|
}
|
|
|
|
if result.is_empty() {
|
|
RESET.to_string()
|
|
} else {
|
|
result
|
|
}
|
|
}
|
|
|
|
/// Determine whether color output should be used.
|
|
pub fn should_use_color(cli_color: Option<&str>, config_color: &crate::config::ColorMode) -> bool {
|
|
if std::env::var("NO_COLOR").is_ok() {
|
|
return false;
|
|
}
|
|
|
|
if let Some(flag) = cli_color {
|
|
return match flag {
|
|
"always" => true,
|
|
"never" => false,
|
|
_ => atty_stdout(),
|
|
};
|
|
}
|
|
|
|
match config_color {
|
|
crate::config::ColorMode::Always => true,
|
|
crate::config::ColorMode::Never => false,
|
|
crate::config::ColorMode::Auto => {
|
|
atty_stdout() && std::env::var("TERM").map_or(true, |t| t != "dumb")
|
|
}
|
|
}
|
|
}
|
|
|
|
fn atty_stdout() -> bool {
|
|
unsafe { libc::isatty(libc::STDOUT_FILENO) != 0 }
|
|
}
|