use std::path::{Path, PathBuf};
use crate::config::Position;
use crate::context::SystemContext;
use crate::shell::{Shell, ShellKind};
pub struct Nushell;
impl Shell for Nushell {
fn kind(&self) -> ShellKind {
ShellKind::Nushell
}
fn env_extension(&self) -> &'static str {
".nu"
}
fn env_script(&self, dir: &Path, position: Position) -> String {
let dir = dir.display();
let mutation = match position {
Position::Prepend => format!("$env.PATH = ($env.PATH | prepend \"{dir}\")"),
Position::Append => format!("$env.PATH = ($env.PATH | append \"{dir}\")"),
};
format!(
r#"# Generated by onpath. Do not edit.
if not ($env.PATH | split row (char esep) | any {{|p| $p == "{dir}"}}) {{
{mutation}
}}
"#
)
}
fn source_line(&self, env_script_path: &Path) -> String {
format!("source \"{}\"", env_script_path.display())
}
fn rc_candidates(&self, ctx: &SystemContext) -> Vec<PathBuf> {
let config = ctx.xdg_config_home();
vec![
config.join("nushell").join("env.nu"),
config.join("nushell").join("config.nu"),
]
}
fn primary_rc(&self, ctx: &SystemContext) -> PathBuf {
ctx.xdg_config_home().join("nushell").join("env.nu")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn env_script_uses_nushell_syntax() {
let script = Nushell.env_script(Path::new("/app/bin"), Position::Prepend);
assert!(script.contains("$env.PATH"));
assert!(script.contains("split row (char esep)"));
assert!(script.contains("prepend"));
}
#[test]
fn env_script_append() {
let script = Nushell.env_script(Path::new("/app/bin"), Position::Append);
assert!(script.contains("append"));
}
#[test]
fn primary_rc_is_env_nu() {
let ctx = SystemContext::with_home(PathBuf::from("/home/user"));
assert_eq!(
Nushell.primary_rc(&ctx),
PathBuf::from("/home/user/.config/nushell/env.nu")
);
}
}