mirror of
https://github.com/starship/starship.git
synced 2024-10-05 01:43:46 +02:00
feat(loadavg): add module for load average
Inspired by https://github.com/starship/starship/discussions/1252#discussioncomment-347145 Example configuration: [loadavg] disabled = false [[loadavg.display]] threshold_one = 8.0 style = "bold red" [[loadavg.display]] threshold_one = 4.0 style = "bold yellow" [[loadavg.display]] threshold_one = 2.0 style = "bold white" [[loadavg.display]] threshold_one = 0.0 style = "dimmed white"
This commit is contained in:
parent
1447957e97
commit
3a864f180b
86
.github/config-schema.json
vendored
86
.github/config-schema.json
vendored
@ -912,6 +912,27 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"loadavg": {
|
||||
"default": {
|
||||
"disabled": true,
|
||||
"display": [
|
||||
{
|
||||
"style": "white bold",
|
||||
"symbol": null,
|
||||
"threshold_fifteen": null,
|
||||
"threshold_five": null,
|
||||
"threshold_one": null
|
||||
}
|
||||
],
|
||||
"format": "[$symbol $one $five $fifteen]($style) ",
|
||||
"symbol": "⌛"
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/LoadavgConfig"
|
||||
}
|
||||
]
|
||||
},
|
||||
"localip": {
|
||||
"default": {
|
||||
"disabled": true,
|
||||
@ -3930,6 +3951,71 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"LoadavgConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"format": {
|
||||
"default": "[$symbol $one $five $fifteen]($style) ",
|
||||
"type": "string"
|
||||
},
|
||||
"symbol": {
|
||||
"default": "⌛",
|
||||
"type": "string"
|
||||
},
|
||||
"display": {
|
||||
"default": [
|
||||
{
|
||||
"style": "white bold",
|
||||
"symbol": null,
|
||||
"threshold_fifteen": null,
|
||||
"threshold_five": null,
|
||||
"threshold_one": null
|
||||
}
|
||||
],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/LoadavgDisplayConfig"
|
||||
}
|
||||
},
|
||||
"disabled": {
|
||||
"default": true,
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"LoadavgDisplayConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"threshold_one": {
|
||||
"default": null,
|
||||
"type": "number",
|
||||
"format": "float"
|
||||
},
|
||||
"threshold_five": {
|
||||
"default": null,
|
||||
"type": "number",
|
||||
"format": "float"
|
||||
},
|
||||
"threshold_fifteen": {
|
||||
"default": null,
|
||||
"type": "number",
|
||||
"format": "float"
|
||||
},
|
||||
"style": {
|
||||
"default": "white bold",
|
||||
"type": "string"
|
||||
},
|
||||
"symbol": {
|
||||
"default": null,
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"LocalipConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -321,6 +321,7 @@ $nix_shell\
|
||||
$conda\
|
||||
$meson\
|
||||
$spack\
|
||||
$loadavg\
|
||||
$memory_usage\
|
||||
$aws\
|
||||
$gcloud\
|
||||
@ -2516,6 +2517,88 @@ The `line_break` module separates the prompt into two lines.
|
||||
disabled = true
|
||||
```
|
||||
|
||||
## Load Average
|
||||
|
||||
The `loadavg` module shows current system load average.
|
||||
|
||||
::: tip
|
||||
|
||||
This module is disabled by default.
|
||||
To enable it, set `disabled` to `false` and define at least one `Load Average Display` in your configuration file.
|
||||
|
||||
:::
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Default | Description |
|
||||
| ---------- | ------------------------------------------ | --------------------------------------------------- |
|
||||
| `format` | `'[$symbol $one $five $fifteen]($style) '` | The format for the module. |
|
||||
| `symbol` | `"⌛"` | The symbol used before displaying the load average. |
|
||||
| `disabled` | `true` | Disables the `loadavg` module. |
|
||||
|
||||
### Variables
|
||||
|
||||
| Variable | Example | Description |
|
||||
| -------- | ------- | ------------------------------------ |
|
||||
| one | `1.42` | The one minute load average. |
|
||||
| five | `2.01` | The five minute load average. |
|
||||
| fifteen | `10.98` | The fifteen minute load average. |
|
||||
| symbol | `⌛` | Mirrors the value of option `symbol` |
|
||||
| style\* | | Mirrors the value of option `style` |
|
||||
|
||||
*: This variable can only be used as a part of a style string
|
||||
|
||||
### Example
|
||||
|
||||
```toml
|
||||
# ~/.config/starship.toml
|
||||
|
||||
[loadavg]
|
||||
disabled = false
|
||||
```
|
||||
|
||||
### Load Average Display
|
||||
|
||||
The `display` configuration option is used to define when the `Load Average` should be shown (threshold-*), which symbol would be used (symbol).
|
||||
If no `display` is provided.
|
||||
|
||||
By default, the thresholds are set to an invalid value.
|
||||
|
||||
The default value for the `symbol` option is the value of `loadavg`'s `symbol` option.
|
||||
|
||||
#### Options
|
||||
|
||||
The `display` option is an array of the following table.
|
||||
|
||||
| Option | Default | Description |
|
||||
| ------------------- | -------------- | --------------------------------------------------------------------------------------------- |
|
||||
| `threshold-one` | `NAN` | The lower bound for the one minute average. |
|
||||
| `threshold-five` | `NAN` | The lower bound for the five minute average. |
|
||||
| `threshold-fifteen` | `NAN` | The lower bound for the fifteen minute average. |
|
||||
| `style` | `'white bold'` | The style used if the display option is in use. |
|
||||
| `symbol` | | Optional symbol displayed if display option is in use, defaults to loadavg's `symbol` option. |
|
||||
|
||||
#### Example
|
||||
|
||||
```toml
|
||||
[[loadavg.display]]
|
||||
threshold_one = 8.0
|
||||
style = "bold red"
|
||||
|
||||
[[loadavg.display]]
|
||||
threshold_one = 4.0
|
||||
style = "bold yellow"
|
||||
|
||||
[[loadavg.display]]
|
||||
threshold_one = 2.0
|
||||
style = "bold white"
|
||||
|
||||
[[loadavg.display]]
|
||||
threshold_one = 0.0
|
||||
style = "dimmed white"
|
||||
symbol = "⏲"
|
||||
```
|
||||
|
||||
## Local IP
|
||||
|
||||
The `localip` module shows the IPv4 address of the primary network interface.
|
||||
|
54
src/configs/loadavg.rs
Normal file
54
src/configs/loadavg.rs
Normal file
@ -0,0 +1,54 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
#[cfg_attr(
|
||||
feature = "config-schema",
|
||||
derive(schemars::JsonSchema),
|
||||
schemars(deny_unknown_fields)
|
||||
)]
|
||||
#[serde(default)]
|
||||
pub struct LoadavgConfig<'a> {
|
||||
pub format: &'a str,
|
||||
pub symbol: &'a str,
|
||||
#[serde(borrow)]
|
||||
pub display: Vec<LoadavgDisplayConfig<'a>>,
|
||||
pub disabled: bool,
|
||||
}
|
||||
|
||||
impl<'a> Default for LoadavgConfig<'a> {
|
||||
fn default() -> Self {
|
||||
LoadavgConfig {
|
||||
format: "[$symbol $one $five $fifteen]($style) ",
|
||||
symbol: "⌛",
|
||||
display: vec![LoadavgDisplayConfig::default()],
|
||||
disabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
#[cfg_attr(
|
||||
feature = "config-schema",
|
||||
derive(schemars::JsonSchema),
|
||||
schemars(deny_unknown_fields)
|
||||
)]
|
||||
#[serde(default)]
|
||||
pub struct LoadavgDisplayConfig<'a> {
|
||||
pub threshold_one: f32,
|
||||
pub threshold_five: f32,
|
||||
pub threshold_fifteen: f32,
|
||||
pub style: &'a str,
|
||||
pub symbol: Option<&'a str>,
|
||||
}
|
||||
|
||||
impl<'a> Default for LoadavgDisplayConfig<'a> {
|
||||
fn default() -> Self {
|
||||
LoadavgDisplayConfig {
|
||||
threshold_one: f32::NAN,
|
||||
threshold_five: f32::NAN,
|
||||
threshold_fifteen: f32::NAN,
|
||||
style: "white bold",
|
||||
symbol: None,
|
||||
}
|
||||
}
|
||||
}
|
@ -48,6 +48,7 @@ pub mod julia;
|
||||
pub mod kotlin;
|
||||
pub mod kubernetes;
|
||||
pub mod line_break;
|
||||
pub mod loadavg;
|
||||
pub mod localip;
|
||||
pub mod lua;
|
||||
pub mod memory_usage;
|
||||
@ -197,6 +198,8 @@ pub struct FullConfig<'a> {
|
||||
kubernetes: kubernetes::KubernetesConfig<'a>,
|
||||
line_break: line_break::LineBreakConfig,
|
||||
#[serde(borrow)]
|
||||
loadavg: loadavg::LoadavgConfig<'a>,
|
||||
#[serde(borrow)]
|
||||
localip: localip::LocalipConfig<'a>,
|
||||
#[serde(borrow)]
|
||||
lua: lua::LuaConfig<'a>,
|
||||
|
@ -98,6 +98,7 @@ pub const PROMPT_ORDER: &[&str] = &[
|
||||
"conda",
|
||||
"meson",
|
||||
"spack",
|
||||
"loadavg",
|
||||
"memory_usage",
|
||||
"aws",
|
||||
"gcloud",
|
||||
|
@ -55,6 +55,7 @@ pub const ALL_MODULES: &[&str] = &[
|
||||
"kotlin",
|
||||
"kubernetes",
|
||||
"line_break",
|
||||
"loadavg",
|
||||
"localip",
|
||||
"lua",
|
||||
"memory_usage",
|
||||
|
162
src/modules/loadavg.rs
Normal file
162
src/modules/loadavg.rs
Normal file
@ -0,0 +1,162 @@
|
||||
use systemstat::{LoadAverage, Platform, System};
|
||||
|
||||
use super::{Context, Module, ModuleConfig};
|
||||
|
||||
use crate::configs::loadavg::{LoadavgConfig, LoadavgDisplayConfig};
|
||||
use crate::formatter::StringFormatter;
|
||||
|
||||
// Check whether a display config is active
|
||||
fn is_active(config: &LoadavgDisplayConfig, loadavg: &LoadAverage) -> bool {
|
||||
config.threshold_one <= loadavg.one
|
||||
|| config.threshold_five <= loadavg.five
|
||||
|| config.threshold_fifteen <= loadavg.fifteen
|
||||
}
|
||||
|
||||
/// Creates a module with system load average information
|
||||
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
let mut module = context.new_module("loadavg");
|
||||
let config = LoadavgConfig::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 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let system = System::new();
|
||||
|
||||
let loadavg = match system.load_average() {
|
||||
Ok(load) => load,
|
||||
Err(e) => {
|
||||
log::warn!("Failed to retrieve loadavg: {}", e);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
// Parse config under `display`.
|
||||
// Select the first style that match any threshold,
|
||||
// if all thresholds are lower do not display loadavg module.
|
||||
let display_config = config
|
||||
.display
|
||||
.iter()
|
||||
.find(|display_style| is_active(display_style, &loadavg))?;
|
||||
|
||||
let parsed = StringFormatter::new(config.format).and_then(|formatter| {
|
||||
formatter
|
||||
.map_meta(|var, _| match var {
|
||||
"symbol" => display_config.symbol.or(Some(config.symbol)),
|
||||
_ => None,
|
||||
})
|
||||
.map_style(|variable| match variable {
|
||||
"style" => Some(Ok(display_config.style)),
|
||||
_ => None,
|
||||
})
|
||||
.map(|variable| match variable {
|
||||
"one" => Some(Ok(format!("{:.2}", loadavg.one))),
|
||||
"five" => Some(Ok(format!("{:.2}", loadavg.five))),
|
||||
"fifteen" => Some(Ok(format!("{:.2}", loadavg.fifteen))),
|
||||
_ => None,
|
||||
})
|
||||
.parse(None, Some(context))
|
||||
});
|
||||
|
||||
module.set_segments(match parsed {
|
||||
Ok(segments) => segments,
|
||||
Err(error) => {
|
||||
log::warn!("Error in module `loadavg`:\n{}", error);
|
||||
return None;
|
||||
}
|
||||
});
|
||||
|
||||
Some(module)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
use crate::test::ModuleRenderer;
|
||||
|
||||
#[test]
|
||||
fn test_is_active() {
|
||||
let mut config: LoadavgDisplayConfig = LoadavgDisplayConfig::default();
|
||||
let loadavg: LoadAverage = LoadAverage {
|
||||
one: 1.0,
|
||||
five: 4.0,
|
||||
fifteen: 8.0,
|
||||
};
|
||||
|
||||
assert!(!is_active(&config, &loadavg));
|
||||
|
||||
config.threshold_one = 1.1;
|
||||
assert!(!is_active(&config, &loadavg));
|
||||
|
||||
config.threshold_one = 1.0;
|
||||
assert!(is_active(&config, &loadavg));
|
||||
|
||||
config.threshold_one = f32::NAN;
|
||||
config.threshold_fifteen = 8.1;
|
||||
assert!(!is_active(&config, &loadavg));
|
||||
|
||||
config.threshold_fifteen = 8.0;
|
||||
assert!(is_active(&config, &loadavg));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zero_threshold() {
|
||||
let output = ModuleRenderer::new("loadavg")
|
||||
.config(toml::toml! {
|
||||
[loadavg]
|
||||
disabled = false
|
||||
[[loadavg.display]]
|
||||
threshold_one = 0.0
|
||||
})
|
||||
.collect();
|
||||
|
||||
if System::new().load_average().is_ok() {
|
||||
assert!(output.is_some())
|
||||
} else {
|
||||
assert!(output.is_none())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn impossible_threshold() {
|
||||
let output = ModuleRenderer::new("loadavg")
|
||||
.config(toml::toml! {
|
||||
[loadavg]
|
||||
disabled = false
|
||||
[[loadavg.display]]
|
||||
threshold_one = 9999.9
|
||||
[[loadavg.display]]
|
||||
threshold_five = 9999.9
|
||||
[[loadavg.display]]
|
||||
threshold_fifteen = 9999.9
|
||||
})
|
||||
.collect();
|
||||
|
||||
assert!(output.is_none())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zero_last_threshold() {
|
||||
let output = ModuleRenderer::new("loadavg")
|
||||
.config(toml::toml! {
|
||||
[loadavg]
|
||||
disabled = false
|
||||
[[loadavg.display]]
|
||||
threshold_one = 9999.9
|
||||
[[loadavg.display]]
|
||||
threshold_five = 9999.9
|
||||
[[loadavg.display]]
|
||||
threshold_fifteen = 0.0
|
||||
})
|
||||
.collect();
|
||||
|
||||
if System::new().load_average().is_ok() {
|
||||
assert!(output.is_some())
|
||||
} else {
|
||||
assert!(output.is_none())
|
||||
}
|
||||
}
|
||||
}
|
@ -45,6 +45,7 @@ mod julia;
|
||||
mod kotlin;
|
||||
mod kubernetes;
|
||||
mod line_break;
|
||||
mod loadavg;
|
||||
mod localip;
|
||||
mod lua;
|
||||
mod memory_usage;
|
||||
@ -148,6 +149,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option<Module<'a>> {
|
||||
"kotlin" => kotlin::module(context),
|
||||
"kubernetes" => kubernetes::module(context),
|
||||
"line_break" => line_break::module(context),
|
||||
"loadavg" => loadavg::module(context),
|
||||
"localip" => localip::module(context),
|
||||
"lua" => lua::module(context),
|
||||
"memory_usage" => memory_usage::module(context),
|
||||
@ -262,6 +264,7 @@ pub fn description(module: &str) -> &'static str {
|
||||
"kotlin" => "The currently installed version of Kotlin",
|
||||
"kubernetes" => "The current Kubernetes context name and, if set, the namespace",
|
||||
"line_break" => "Separates the prompt into two lines",
|
||||
"loadavg" => "The current system load average",
|
||||
"localip" => "The currently assigned ipv4 address",
|
||||
"lua" => "The currently installed version of Lua",
|
||||
"memory_usage" => "Current system memory and swap usage",
|
||||
|
Loading…
Reference in New Issue
Block a user