use crate::{Block, Color, Environment, Icon, IconMode, Pretty, Style, WithStyle as _};
use std::{ffi::OsStr, path::Path};
pub struct NixShell {
purity: bool,
build_inputs: Vec<String>,
native_build_inputs: Vec<String>,
}
super::register_block!(NixShell);
impl Block for NixShell {
fn new(_: &Environment) -> Option<Self> {
let purity = match std::env::var("IN_NIX_SHELL").ok()?.as_ref() {
"impure" => false,
"pure" => true,
_ => return None,
};
let inputs_from_env = |name| {
std::env::var(name)
.unwrap_or_default()
.split_whitespace()
.map(Path::new)
.filter_map(Path::file_name)
.filter_map(OsStr::to_str)
.filter_map(|s| s.split_once('-'))
.map(|(h, p)| format!("{}:{p}", &h[..6]))
.collect()
};
Some(NixShell {
purity,
build_inputs: inputs_from_env("buildInputs"),
native_build_inputs: inputs_from_env("nativeBuildInputs"),
})
}
}
impl Pretty for NixShell {
fn pretty(&self, f: &mut std::fmt::Formatter<'_>, mode: IconMode) -> std::fmt::Result {
f.with_style(Color::BRIGHT_BLUE, Style::empty(), |f| {
let purity = if self.purity { "" } else { "!" };
write!(f, "[{purity}{}", self.icon(mode))?;
let mut format_inputs = |name, inputs: &[String]| match &inputs {
[] => Ok(()),
[input] => write!(f, " {input}"),
_ => write!(f, " {name}/{}", inputs.len()),
};
format_inputs("bi", &self.build_inputs)?;
format_inputs("nbi", &self.native_build_inputs)?;
write!(f, "]")?;
Ok(())
})
}
}
impl Icon for NixShell {
fn icon(&self, mode: IconMode) -> &'static str {
use IconMode::*;
match &mode {
Text => "nix",
Icons | MinimalIcons => "",
}
}
}