use crate::ported::bindings::config as binding_config;
use crate::ported::commands::config::{get_argparser, StrFunction};
pub fn main(args: &[String]) -> i32 {
let _parser = get_argparser();
let action_name = match args.first() {
Some(s) => s.as_str(),
None => {
eprintln!("powerline-config: missing function argument");
return 2;
}
};
let _binding = binding_config::deduce_command();
let resolved: Option<StrFunction> =
crate::ported::commands::config::tmux_action_from_name(action_name)
.or_else(|| crate::ported::commands::config::shell_action_from_name(action_name));
match resolved {
Some(StrFunction::Command) => {
match binding_config::deduce_command() {
Some(cmd) => {
println!("{}", cmd);
0
}
None => 1,
}
}
Some(StrFunction::Uses) => {
let component = match args.get(1) {
Some(c) => c.clone(),
None => {
eprintln!("powerline-config uses: component required");
return 1;
}
};
let mut shell: Option<String> = None;
let mut i = 2;
while i < args.len() {
if args[i] == "-s" || args[i] == "--shell" {
if let Some(s) = args.get(i + 1) {
shell = Some(s.clone());
}
i += 2;
} else {
i += 1;
}
}
let sh_list: Vec<String> = match shell.as_deref() {
Some(s) => vec![s.to_string(), "shell".to_string()],
None => vec!["shell".to_string()],
};
for sh in &sh_list {
let varname = format!(
"POWERLINE_NO_{}_{}",
sh.to_uppercase(),
component.to_uppercase()
);
if std::env::var(&varname)
.map(|v| !v.is_empty())
.unwrap_or(false)
{
return 1;
}
}
use crate::ported::lib::config::load_json_config;
use crate::ported::lib::dict::mergedicts;
use crate::ported::{_find_config_files, get_config_paths};
let mut search_paths: Vec<std::path::PathBuf> = Vec::new();
if let Ok(pcp) = std::env::var("POWERLINE_CONFIG_PATHS") {
for p in pcp.split(':').filter(|s| !s.is_empty()) {
search_paths.push(std::path::PathBuf::from(p));
}
}
let mut j = 0;
while j < args.len() {
if args[j] == "--config-path" || args[j] == "-p" {
if let Some(p) = args.get(j + 1) {
search_paths.push(std::path::PathBuf::from(p));
}
j += 2;
} else {
j += 1;
}
}
search_paths.extend(get_config_paths());
let mut config = serde_json::Map::new();
if let Ok(matches) = _find_config_files(&search_paths, "config") {
for path in matches {
if let Ok(v) = load_json_config(&path) {
if let Some(o) = v.as_object().cloned() {
mergedicts(&mut config, o, true);
}
}
}
}
let components: Vec<String> = config
.get("ext")
.and_then(|v| v.as_object())
.and_then(|o| o.get("shell"))
.and_then(|v| v.as_object())
.and_then(|o| o.get("components"))
.and_then(|v| v.as_array())
.map(|a| {
a.iter()
.filter_map(|v| v.as_str().map(String::from))
.collect()
})
.unwrap_or_else(|| vec!["tmux".to_string(), "prompt".to_string()]);
if components.iter().any(|c| c == &component) {
0
} else {
1
}
}
Some(StrFunction::Source) | Some(StrFunction::Setenv) | Some(StrFunction::Setup) => {
eprintln!(
"powerline-config: action '{}' requires the Powerline orchestrator (deferred port)",
action_name
);
1
}
None => {
eprintln!("powerline-config: unknown function '{}'", action_name);
2
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn main_returns_2_when_no_args() {
assert_eq!(main(&[]), 2);
}
#[test]
fn main_returns_2_for_unknown_function() {
let r = main(&["definitely-not-a-real-function".to_string()]);
assert_eq!(r, 2);
}
#[test]
fn main_returns_1_for_tmux_function_requiring_powerline_orchestrator() {
let r = main(&["source".to_string()]);
assert_eq!(r, 1);
}
#[test]
fn main_handles_known_shell_function() {
let r = main(&["command".to_string()]);
assert!(r == 0 || r == 1, "unexpected exit code {}", r);
}
}