use nu_ansi_term::{Color, Style};
use super::classes::resolve_classes;
use super::load::find_config_path;
use super::personality::resolve_personality;
use super::schema::CONFIG_VERSION;
use super::store::config;
use super::styles::resolve_style;
use super::themes::is_builtin_theme;
pub fn show_config(personality_name: &str, activated_by: &str, cli_theme_override: Option<&str>) {
let heading = Style::new().bold().fg(Color::Yellow);
let label = Style::new().bold();
let name = Style::new().bold().fg(Color::Cyan);
let value = Style::new().fg(Color::Green);
let dimmed = Style::new().dimmed();
let config_path = find_config_path();
let cfg = config();
println!("{}", heading.paint("lx configuration"));
println!();
match &config_path {
Some(p) => println!("{} {}", label.paint("Config file:"), value.paint(p.display().to_string())),
None => println!("{} {}", label.paint("Config file:"), dimmed.paint("(none)")),
}
println!("{} {}", label.paint("Config version:"), value.paint(CONFIG_VERSION));
if let Some(cfg) = cfg
&& !cfg.drop_in_paths.is_empty() {
println!("{} {} file(s) from conf.d/", label.paint("Drop-ins:"), value.paint(cfg.drop_in_paths.len().to_string()));
for p in &cfg.drop_in_paths {
println!(" {}", dimmed.paint(p.display().to_string()));
}
}
println!();
println!("{} {}", label.paint("Personality:"), name.paint(personality_name));
let source = if cfg.is_some_and(|c| c.personality.contains_key(personality_name)) {
"config"
} else {
"builtin"
};
println!(" {} {}", label.paint("source:"), dimmed.paint(source));
println!(" {} {}", label.paint("activated by:"), dimmed.paint(activated_by));
if let Ok(Some(p)) = resolve_personality(personality_name) {
if let Some(ref inherits) = p.inherits {
println!(" {} {}", label.paint("inherits:"), name.paint(inherits));
}
if let Some(ref fmt) = p.format {
println!(" {} {}", label.paint("format:"), name.paint(fmt));
}
if let Some(ref cols) = p.columns {
println!(" {} {}", label.paint("columns:"), value.paint(cols.to_csv()));
}
if !p.settings.is_empty() {
println!(" {}",label.paint("settings:"));
let mut keys: Vec<_> = p.settings.keys().collect();
keys.sort();
for key in keys {
println!(" {} = {}", name.paint(key), value.paint(p.settings[key].to_string()));
}
}
}
println!();
let theme_name = cli_theme_override.map(String::from).or_else(|| {
resolve_personality(personality_name)
.ok()
.flatten()
.and_then(|p| p.settings.get("theme").and_then(|v| {
if let toml::Value::String(s) = v { Some(s.clone()) } else { None }
}))
});
if let Some(ref tname) = theme_name {
println!("{} {}", label.paint("Theme:"), name.paint(tname));
let source = if is_builtin_theme(tname) {
"builtin"
} else if cfg.is_some_and(|c| c.theme.contains_key(tname)) {
"config"
} else {
"unknown"
};
println!(" {} {}", label.paint("source:"), dimmed.paint(source));
if is_builtin_theme(tname) {
println!(" {} {} {}", label.paint("use-style:"), name.paint("exa"), dimmed.paint("(implicit)"));
} else if let Some(cfg) = cfg
&& let Some(theme) = cfg.theme.get(tname) {
if let Some(ref inherits) = theme.inherits {
println!(" {} {}", label.paint("inherits:"), name.paint(inherits));
}
if let Some(ref style) = theme.use_style {
println!(" {} {}", label.paint("use-style:"), name.paint(style));
}
}
} else {
println!("{} {}", label.paint("Theme:"), dimmed.paint("(none)"));
}
println!();
let style_name = theme_name.as_deref().and_then(|tn| {
if is_builtin_theme(tn) {
Some("exa".to_string())
} else if let Some(cfg) = cfg {
cfg.theme.get(tn).and_then(|t| t.use_style.clone())
} else {
None
}
});
if let Some(ref sname) = style_name {
println!("{} {}", label.paint("Style:"), name.paint(sname));
let source = if sname == "exa" {
"builtin"
} else if cfg.is_some_and(|c| c.style.contains_key(sname)) {
"config"
} else {
"unknown"
};
println!(" {} {}", label.paint("source:"), dimmed.paint(source));
if let Some(style) = resolve_style(sname) {
if !style.classes.is_empty() {
println!(" {}", label.paint("class references:"));
let mut keys: Vec<_> = style.classes.keys().collect();
keys.sort();
for key in keys {
println!(" {} = {}", name.paint(key), value.paint(format!("\"{}\"", style.classes[key])));
}
}
if !style.patterns.is_empty() {
println!(" {}", label.paint("file patterns:"));
let mut keys: Vec<_> = style.patterns.keys().collect();
keys.sort();
for key in keys {
println!(" {} = {}", name.paint(format!("\"{key}\"")), value.paint(format!("\"{}\"", style.patterns[key])));
}
}
}
} else {
println!("{} {}", label.paint("Style:"), dimmed.paint("(none)"));
}
println!();
let classes = resolve_classes();
println!("{} {} defined", label.paint("Classes:"), value.paint(classes.len().to_string()));
let mut names: Vec<_> = classes.keys().collect();
names.sort();
for cname in names {
let source = if cfg.is_some_and(|c| c.class.contains_key(cname)) {
"config"
} else {
"builtin"
};
let patterns = &classes[cname];
println!(" {} {}: {} patterns",
name.paint(cname), dimmed.paint(format!("({source})")),
value.paint(patterns.len().to_string()));
}
println!();
println!("{}", label.paint("Formats:"));
let compiled = vec!["long", "long2", "long3"];
for fname in &compiled {
let source = if cfg.is_some_and(|c| c.format.contains_key(*fname)) {
"config (overrides builtin)"
} else {
"builtin"
};
println!(" {}: {}", name.paint(*fname), dimmed.paint(source));
}
if let Some(cfg) = cfg {
for fname in cfg.format.keys() {
if !compiled.contains(&fname.as_str()) {
println!(" {}: {}", name.paint(fname), dimmed.paint("config"));
}
}
}
}