mirror of
https://github.com/starship/starship.git
synced 2024-11-29 19:53:38 +01:00
feat: Implement threshold based styling for battery module (#318)
This commit is contained in:
parent
2f94cac5b3
commit
a6c64e8457
@ -109,13 +109,13 @@ The module is only visible when the device's battery is below 10%.
|
|||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
| Variable | Default | Description |
|
| Variable | Default | Description |
|
||||||
| -------------------- | ------------ | ------------------------------------------------- |
|
| -------------------- | ------------------------ | ------------------------------------------------- |
|
||||||
| `full_symbol` | `"•"` | The symbol shown when the battery is full. |
|
| `full_symbol` | `"•"` | The symbol shown when the battery is full. |
|
||||||
| `charging_symbol` | `"⇡"` | The symbol shown when the battery is charging. |
|
| `charging_symbol` | `"⇡"` | The symbol shown when the battery is charging. |
|
||||||
| `discharging_symbol` | `"⇣"` | The symbol shown when the battery is discharging. |
|
| `discharging_symbol` | `"⇣"` | The symbol shown when the battery is discharging. |
|
||||||
| `style` | `"bold red"` | The style for the module. |
|
| `display` | [link](#battery-display) | Display threshold and style for the module. |
|
||||||
| `disabled` | `false` | Disables the `battery` module. |
|
| `disabled` | `false` | Disables the `battery` module. |
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
@ -128,6 +128,41 @@ charging_symbol = "⚡️"
|
|||||||
discharging_symbol = "💀"
|
discharging_symbol = "💀"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Battery Display
|
||||||
|
|
||||||
|
The `display` configuration option is used to define when the battery indicator should be shown (threshold) and what it looks like (style).
|
||||||
|
If no `display` is provided. The default is as shown:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[[battery.display]]
|
||||||
|
threshold = 10
|
||||||
|
style = "bold red"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Options
|
||||||
|
|
||||||
|
The `display` option is an array of the following table.
|
||||||
|
|
||||||
|
| Variable | Description |
|
||||||
|
|-------------|-------------------------------------------------|
|
||||||
|
| `threshold` | The upper bound for the display option. |
|
||||||
|
| `style` | The style used if the display option is in use. |
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[[battery.display]] # "bold red" style when capacity is between 0% and 10%
|
||||||
|
threshold = 10
|
||||||
|
style = "bold red"
|
||||||
|
|
||||||
|
[[battery.display]] # "bold yellow" style when capacity is between 10% and 30%
|
||||||
|
threshold = 30
|
||||||
|
style = "bold yellow"
|
||||||
|
|
||||||
|
# when capacity is over 30%, the battery indicator will not be displayed
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## Character
|
## Character
|
||||||
|
|
||||||
The `character` module shows a character (usually an arrow) beside where the text
|
The `character` module shows a character (usually an arrow) beside where the text
|
||||||
|
@ -145,6 +145,11 @@ impl<'a> Module<'a> {
|
|||||||
pub fn config_value_style(&self, key: &str) -> Option<Style> {
|
pub fn config_value_style(&self, key: &str) -> Option<Style> {
|
||||||
self.config.and_then(|config| config.get_as_ansi_style(key))
|
self.config.and_then(|config| config.get_as_ansi_style(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a module's config value as an array
|
||||||
|
pub fn config_value_array(&self, key: &str) -> Option<&Vec<toml::Value>> {
|
||||||
|
self.config.and_then(|config| config.get_as_array(key))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> fmt::Display for Module<'a> {
|
impl<'a> fmt::Display for Module<'a> {
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
use ansi_term::Color;
|
use ansi_term::{Color, Style};
|
||||||
|
|
||||||
use super::{Context, Module};
|
use super::{Context, Module};
|
||||||
|
use crate::config::Config;
|
||||||
|
|
||||||
/// Creates a module for the battery percentage and charging state
|
/// Creates a module for the battery percentage and charging state
|
||||||
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||||
const BATTERY_FULL: &str = "•";
|
const BATTERY_FULL: &str = "•";
|
||||||
const BATTERY_CHARGING: &str = "⇡";
|
const BATTERY_CHARGING: &str = "⇡";
|
||||||
const BATTERY_DISCHARGING: &str = "⇣";
|
const BATTERY_DISCHARGING: &str = "⇣";
|
||||||
const BATTERY_THRESHOLD: f32 = 10.0;
|
|
||||||
// TODO: Update when v1.0 printing refactor is implemented to only
|
// TODO: Update when v1.0 printing refactor is implemented to only
|
||||||
// print escapes in a prompt context.
|
// print escapes in a prompt context.
|
||||||
let shell = std::env::var("STARSHIP_SHELL").unwrap_or_default();
|
let shell = std::env::var("STARSHIP_SHELL").unwrap_or_default();
|
||||||
@ -19,43 +19,67 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
|||||||
let battery_status = get_battery_status()?;
|
let battery_status = get_battery_status()?;
|
||||||
let BatteryStatus { state, percentage } = battery_status;
|
let BatteryStatus { state, percentage } = battery_status;
|
||||||
|
|
||||||
if percentage > BATTERY_THRESHOLD {
|
|
||||||
log::debug!(
|
|
||||||
"Battery percentage is higher than threshold ({} > {})",
|
|
||||||
percentage,
|
|
||||||
BATTERY_THRESHOLD
|
|
||||||
);
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Set style based on percentage when threshold is modifiable
|
|
||||||
let mut module = context.new_module("battery");
|
let mut module = context.new_module("battery");
|
||||||
let module_style = module
|
|
||||||
.config_value_style("style")
|
|
||||||
.unwrap_or_else(|| Color::Red.bold());
|
|
||||||
module.set_style(module_style);
|
|
||||||
module.get_prefix().set_value("");
|
|
||||||
|
|
||||||
match state {
|
// Parse config under `display`
|
||||||
battery::State::Full => {
|
let display_styles = get_display_styles(&module);
|
||||||
module.new_segment("full_symbol", BATTERY_FULL);
|
let display_style = display_styles.iter().find(|display_style| {
|
||||||
|
let BatteryDisplayStyle { threshold, .. } = display_style;
|
||||||
|
percentage <= *threshold as f32
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(display_style) = display_style {
|
||||||
|
let BatteryDisplayStyle { style, .. } = display_style;
|
||||||
|
|
||||||
|
// Set style based on percentage
|
||||||
|
module.set_style(*style);
|
||||||
|
module.get_prefix().set_value("");
|
||||||
|
|
||||||
|
match state {
|
||||||
|
battery::State::Full => {
|
||||||
|
module.new_segment("full_symbol", BATTERY_FULL);
|
||||||
|
}
|
||||||
|
battery::State::Charging => {
|
||||||
|
module.new_segment("charging_symbol", BATTERY_CHARGING);
|
||||||
|
}
|
||||||
|
battery::State::Discharging => {
|
||||||
|
module.new_segment("discharging_symbol", BATTERY_DISCHARGING);
|
||||||
|
}
|
||||||
|
_ => return None,
|
||||||
}
|
}
|
||||||
battery::State::Charging => {
|
|
||||||
module.new_segment("charging_symbol", BATTERY_CHARGING);
|
let mut percent_string = Vec::<String>::with_capacity(2);
|
||||||
}
|
// Round the percentage to a whole number
|
||||||
battery::State::Discharging => {
|
percent_string.push(percentage.round().to_string());
|
||||||
module.new_segment("discharging_symbol", BATTERY_DISCHARGING);
|
percent_string.push(percentage_char.to_string());
|
||||||
}
|
module.new_segment("percentage", percent_string.join("").as_ref());
|
||||||
_ => return None,
|
|
||||||
|
Some(module)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut percent_string = Vec::<String>::with_capacity(2);
|
fn get_display_styles(module: &Module) -> Vec<BatteryDisplayStyle> {
|
||||||
// Round the percentage to a whole number
|
if let Some(display_configs) = module.config_value_array("display") {
|
||||||
percent_string.push(percentage.round().to_string());
|
let mut display_styles: Vec<BatteryDisplayStyle> = vec![];
|
||||||
percent_string.push(percentage_char.to_string());
|
for display_config in display_configs.iter() {
|
||||||
module.new_segment("percentage", percent_string.join("").as_ref());
|
if let toml::Value::Table(config) = display_config {
|
||||||
|
if let Some(display_style) = BatteryDisplayStyle::from_config(config) {
|
||||||
|
display_styles.push(display_style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Some(module)
|
// Return display styles as long as display array exists, even if it is empty.
|
||||||
|
display_styles
|
||||||
|
} else {
|
||||||
|
// Default display styles: [{ threshold = 10, style = "red bold" }]
|
||||||
|
vec![BatteryDisplayStyle {
|
||||||
|
threshold: 10,
|
||||||
|
style: Color::Red.bold(),
|
||||||
|
}]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_battery_status() -> Option<BatteryStatus> {
|
fn get_battery_status() -> Option<BatteryStatus> {
|
||||||
@ -85,3 +109,19 @@ struct BatteryStatus {
|
|||||||
percentage: f32,
|
percentage: f32,
|
||||||
state: battery::State,
|
state: battery::State,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct BatteryDisplayStyle {
|
||||||
|
threshold: i64,
|
||||||
|
style: Style,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BatteryDisplayStyle {
|
||||||
|
/// construct battery display style from toml table
|
||||||
|
pub fn from_config(config: &toml::value::Table) -> Option<BatteryDisplayStyle> {
|
||||||
|
let threshold = config.get_as_i64("threshold")?;
|
||||||
|
let style = config.get_as_ansi_style("style")?;
|
||||||
|
|
||||||
|
Some(BatteryDisplayStyle { threshold, style })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user