261 lines
7.1 KiB
Rust
261 lines
7.1 KiB
Rust
use super::{Context, Module};
|
|
|
|
use crate::config::ModuleConfig;
|
|
use crate::configs::shlvl::ShLvlConfig;
|
|
use crate::formatter::StringFormatter;
|
|
use std::borrow::Cow;
|
|
use std::convert::TryInto;
|
|
|
|
const SHLVL_ENV_VAR: &str = "SHLVL";
|
|
|
|
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
|
let shlvl = context.get_env(SHLVL_ENV_VAR)?.parse::<i64>().ok()?;
|
|
|
|
let mut module = context.new_module("shlvl");
|
|
let config: ShLvlConfig = ShLvlConfig::try_load(module.config);
|
|
|
|
// As we default to disabled=true, we have to check here after loading our config module,
|
|
// before it was only checking against whatever is in the config starship.toml
|
|
if config.disabled || shlvl < config.threshold {
|
|
return None;
|
|
}
|
|
|
|
let shlvl_str = &shlvl.to_string();
|
|
|
|
let mut repeat_count: usize = if config.repeat {
|
|
shlvl.try_into().unwrap_or(1)
|
|
} else {
|
|
1
|
|
};
|
|
|
|
if config.repeat_offset > 0 {
|
|
repeat_count =
|
|
repeat_count.saturating_sub(config.repeat_offset.try_into().unwrap_or(usize::MAX));
|
|
if repeat_count == 0 {
|
|
return None;
|
|
}
|
|
}
|
|
|
|
let symbol = if repeat_count != 1 {
|
|
Cow::Owned(config.symbol.repeat(repeat_count))
|
|
} else {
|
|
Cow::Borrowed(config.symbol)
|
|
};
|
|
|
|
let parsed = StringFormatter::new(config.format).and_then(|formatter| {
|
|
formatter
|
|
.map_meta(|var, _| match var {
|
|
"symbol" => Some(symbol.as_ref()),
|
|
_ => None,
|
|
})
|
|
.map_style(|variable| match variable {
|
|
"style" => Some(Ok(config.style)),
|
|
_ => None,
|
|
})
|
|
.map(|variable| match variable {
|
|
"shlvl" => Some(Ok(shlvl_str)),
|
|
_ => None,
|
|
})
|
|
.parse(None, Some(context))
|
|
});
|
|
|
|
module.set_segments(match parsed {
|
|
Ok(segments) => segments,
|
|
Err(error) => {
|
|
log::warn!("Error in module `shlvl`:\n{}", error);
|
|
return None;
|
|
}
|
|
});
|
|
|
|
Some(module)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use nu_ansi_term::{Color, Style};
|
|
|
|
use crate::test::ModuleRenderer;
|
|
|
|
use super::SHLVL_ENV_VAR;
|
|
|
|
fn style() -> Style {
|
|
// default style
|
|
Color::Yellow.bold()
|
|
}
|
|
|
|
#[test]
|
|
fn empty_config() {
|
|
let actual = ModuleRenderer::new("shlvl")
|
|
.config(toml::toml! {
|
|
[shlvl]
|
|
})
|
|
.env(SHLVL_ENV_VAR, "2")
|
|
.collect();
|
|
let expected = None;
|
|
|
|
assert_eq!(expected, actual);
|
|
}
|
|
|
|
#[test]
|
|
fn enabled() {
|
|
let actual = ModuleRenderer::new("shlvl")
|
|
.config(toml::toml! {
|
|
[shlvl]
|
|
disabled = false
|
|
})
|
|
.env(SHLVL_ENV_VAR, "2")
|
|
.collect();
|
|
let expected = Some(format!("{} ", style().paint("↕️ 2")));
|
|
|
|
assert_eq!(expected, actual);
|
|
}
|
|
|
|
#[test]
|
|
fn no_level() {
|
|
let actual = ModuleRenderer::new("shlvl")
|
|
.config(toml::toml! {
|
|
[shlvl]
|
|
disabled = false
|
|
})
|
|
.collect();
|
|
let expected = None;
|
|
|
|
assert_eq!(expected, actual);
|
|
}
|
|
|
|
#[test]
|
|
fn enabled_config_level_1() {
|
|
let actual = ModuleRenderer::new("shlvl")
|
|
.config(toml::toml! {
|
|
[shlvl]
|
|
disabled = false
|
|
})
|
|
.env(SHLVL_ENV_VAR, "1")
|
|
.collect();
|
|
let expected = None;
|
|
|
|
assert_eq!(expected, actual);
|
|
}
|
|
|
|
#[test]
|
|
fn lower_threshold() {
|
|
let actual = ModuleRenderer::new("shlvl")
|
|
.config(toml::toml! {
|
|
[shlvl]
|
|
threshold = 1
|
|
disabled = false
|
|
})
|
|
.env(SHLVL_ENV_VAR, "1")
|
|
.collect();
|
|
let expected = Some(format!("{} ", style().paint("↕️ 1")));
|
|
|
|
assert_eq!(expected, actual);
|
|
}
|
|
|
|
#[test]
|
|
fn higher_threshold() {
|
|
let actual = ModuleRenderer::new("shlvl")
|
|
.config(toml::toml! {
|
|
[shlvl]
|
|
threshold = 3
|
|
disabled = false
|
|
})
|
|
.env(SHLVL_ENV_VAR, "1")
|
|
.collect();
|
|
let expected = None;
|
|
|
|
assert_eq!(expected, actual);
|
|
}
|
|
|
|
#[test]
|
|
fn custom_style() {
|
|
let actual = ModuleRenderer::new("shlvl")
|
|
.config(toml::toml! {
|
|
[shlvl]
|
|
style = "Red Underline"
|
|
disabled = false
|
|
})
|
|
.env(SHLVL_ENV_VAR, "2")
|
|
.collect();
|
|
let expected = Some(format!("{} ", Color::Red.underline().paint("↕️ 2")));
|
|
|
|
assert_eq!(expected, actual);
|
|
}
|
|
|
|
#[test]
|
|
fn custom_symbol() {
|
|
let actual = ModuleRenderer::new("shlvl")
|
|
.config(toml::toml! {
|
|
[shlvl]
|
|
symbol = "shlvl is "
|
|
disabled = false
|
|
})
|
|
.env(SHLVL_ENV_VAR, "2")
|
|
.collect();
|
|
let expected = Some(format!("{} ", style().paint("shlvl is 2")));
|
|
|
|
assert_eq!(expected, actual);
|
|
}
|
|
|
|
#[test]
|
|
fn formatting() {
|
|
let actual = ModuleRenderer::new("shlvl")
|
|
.config(toml::toml! {
|
|
[shlvl]
|
|
format = "$symbol going down [$shlvl]($style) GOING UP "
|
|
disabled = false
|
|
})
|
|
.env(SHLVL_ENV_VAR, "2")
|
|
.collect();
|
|
let expected = Some(format!("↕️ going down {} GOING UP ", style().paint("2")));
|
|
|
|
assert_eq!(expected, actual);
|
|
}
|
|
|
|
#[test]
|
|
fn repeat() {
|
|
let actual = ModuleRenderer::new("shlvl")
|
|
.config(toml::toml! {
|
|
[shlvl]
|
|
format = "[$symbol>]($style) "
|
|
symbol = "~"
|
|
repeat = true
|
|
disabled = false
|
|
})
|
|
.env(SHLVL_ENV_VAR, "3")
|
|
.collect();
|
|
let expected = Some(format!("{} ", style().paint("~~~>")));
|
|
|
|
assert_eq!(expected, actual);
|
|
}
|
|
|
|
#[test]
|
|
fn repeat_offset() {
|
|
fn get_actual(shlvl: usize, repeat_offset: usize, threshold: usize) -> Option<String> {
|
|
ModuleRenderer::new("shlvl")
|
|
.config(toml::toml! {
|
|
[shlvl]
|
|
format = "[$symbol]($style)"
|
|
symbol = "~"
|
|
repeat = true
|
|
repeat_offset = repeat_offset
|
|
disabled = false
|
|
threshold = threshold
|
|
})
|
|
.env(SHLVL_ENV_VAR, format!("{}", shlvl))
|
|
.collect()
|
|
}
|
|
|
|
assert_eq!(
|
|
get_actual(2, 0, 0),
|
|
Some(format!("{}", style().paint("~~")))
|
|
);
|
|
assert_eq!(get_actual(2, 1, 0), Some(format!("{}", style().paint("~"))));
|
|
assert_eq!(get_actual(2, 2, 0), None); // offset same as shlvl; hide
|
|
assert_eq!(get_actual(2, 3, 0), None); // offset larger than shlvl; hide
|
|
assert_eq!(get_actual(2, 1, 3), None); // high threshold; hide
|
|
// threshold not high enough; hide
|
|
assert_eq!(get_actual(2, 1, 2), Some(format!("{}", style().paint("~"))));
|
|
}
|
|
}
|