From 3ab8e26e77918657ae0957c3fa938daca3d87728 Mon Sep 17 00:00:00 2001 From: RaresCon Date: Wed, 11 Jan 2023 14:59:44 +0200 Subject: [PATCH 1/8] Added dynamic battery widget For bottom to know that there are no batteries on the system, I added the battery::Manager to the options.rs file because here is the first moment bottom verifies battery configuration by reading the config file, which may or may not contain the battery field, but for a better UX, it doesn't matter what bottom finds in the config file now, if it doesn't retrieve battery data, it just ignores the battery widget all together. If needed, it can be adjusted so that if the config file contains the battery field, it will still show the widget. --- docs/content/usage/widgets/battery.md | 2 +- src/options.rs | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/content/usage/widgets/battery.md b/docs/content/usage/widgets/battery.md index 1859a3ba6..b31acb83c 100644 --- a/docs/content/usage/widgets/battery.md +++ b/docs/content/usage/widgets/battery.md @@ -2,7 +2,7 @@ !!! Warning - The battery features are unavailable if the binary is compiled with the `battery` feature disabled! + The battery features are unavailable if the binary is compiled with the `battery` feature disabled or if there are no batteries on the system! The battery widget provides information about batteries on the system. diff --git a/src/options.rs b/src/options.rs index d659b00ad..cbddbda4f 100644 --- a/src/options.rs +++ b/src/options.rs @@ -10,6 +10,7 @@ use clap::ArgMatches; use layout_options::*; use regex::Regex; use serde::{Deserialize, Serialize}; +use starship_battery::Manager; use typed_builder::*; use crate::{ @@ -844,6 +845,14 @@ fn get_hide_table_gap(matches: &ArgMatches, config: &Config) -> bool { } fn get_use_battery(matches: &ArgMatches, config: &Config) -> bool { + if let Ok(battery_manager) = Manager::new() { + if let Ok(batteries) = battery_manager.batteries() { + if batteries.count() == 0 { + return false; + } + } + } + if cfg!(feature = "battery") { if matches.is_present("battery") { return true; From 41e180780eac26e5165efeee82959c0a408a697f Mon Sep 17 00:00:00 2001 From: NitrogenDev <44950964+NitrogenDev@users.noreply.github.com> Date: Fri, 13 Jan 2023 17:55:06 +0200 Subject: [PATCH 2/8] CFG guarding for BATTERY module I guarded the options.rs in two places for battery module that can be missing in the feature list. --- src/options.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/options.rs b/src/options.rs index cbddbda4f..5c1603101 100644 --- a/src/options.rs +++ b/src/options.rs @@ -10,7 +10,10 @@ use clap::ArgMatches; use layout_options::*; use regex::Regex; use serde::{Deserialize, Serialize}; + +#[cfg(feature = "battery")] use starship_battery::Manager; + use typed_builder::*; use crate::{ @@ -845,6 +848,7 @@ fn get_hide_table_gap(matches: &ArgMatches, config: &Config) -> bool { } fn get_use_battery(matches: &ArgMatches, config: &Config) -> bool { + #[cfg(feature = "battery")] if let Ok(battery_manager) = Manager::new() { if let Ok(batteries) = battery_manager.batteries() { if batteries.count() == 0 { From 0b8ff0e7dc768b05b95e9e758778c597fb173e49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rare=C8=99=20Constantin?= <95525840+RaresCon@users.noreply.github.com> Date: Sat, 21 Jan 2023 22:44:35 +0200 Subject: [PATCH 3/8] Revert "Dynamic battery widget" --- docs/content/usage/widgets/battery.md | 2 +- src/options.rs | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/docs/content/usage/widgets/battery.md b/docs/content/usage/widgets/battery.md index b31acb83c..1859a3ba6 100644 --- a/docs/content/usage/widgets/battery.md +++ b/docs/content/usage/widgets/battery.md @@ -2,7 +2,7 @@ !!! Warning - The battery features are unavailable if the binary is compiled with the `battery` feature disabled or if there are no batteries on the system! + The battery features are unavailable if the binary is compiled with the `battery` feature disabled! The battery widget provides information about batteries on the system. diff --git a/src/options.rs b/src/options.rs index 5c1603101..d659b00ad 100644 --- a/src/options.rs +++ b/src/options.rs @@ -10,10 +10,6 @@ use clap::ArgMatches; use layout_options::*; use regex::Regex; use serde::{Deserialize, Serialize}; - -#[cfg(feature = "battery")] -use starship_battery::Manager; - use typed_builder::*; use crate::{ @@ -848,15 +844,6 @@ fn get_hide_table_gap(matches: &ArgMatches, config: &Config) -> bool { } fn get_use_battery(matches: &ArgMatches, config: &Config) -> bool { - #[cfg(feature = "battery")] - if let Ok(battery_manager) = Manager::new() { - if let Ok(batteries) = battery_manager.batteries() { - if batteries.count() == 0 { - return false; - } - } - } - if cfg!(feature = "battery") { if matches.is_present("battery") { return true; From 3c8c87be5d9a8b77b6ee4e3f5833a51135346c70 Mon Sep 17 00:00:00 2001 From: RaresCon Date: Sat, 21 Jan 2023 23:02:35 +0200 Subject: [PATCH 4/8] Added custom terminal title I added a new option in terminal and in the config file to be able to change the terminal title with any custom one. The user can now add `--title` and the custom title after it or add the `title_to_hostname` field in the config file to set the terminal's name to hostname. If there is no option found, then the name of the terminal will be set to "Bottom". --- Cargo.lock | 26 ++++++++++++++++++++++++++ Cargo.toml | 1 + sample_configs/default_config.toml | 2 ++ src/bin/main.rs | 5 +++-- src/clap.rs | 7 +++++++ src/options.rs | 27 +++++++++++++++++++++++++++ 6 files changed, 66 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 60cced73e..da62b15e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -224,6 +224,7 @@ dependencies = [ "futures", "futures-timer", "fxhash", + "gethostname", "heim", "humantime", "humantime-serde", @@ -756,6 +757,16 @@ dependencies = [ "byteorder", ] +[[package]] +name = "gethostname" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a329e22866dd78b35d2c639a4a23d7b950aeae300dfd79f4fb19f74055c2404" +dependencies = [ + "libc", + "windows", +] + [[package]] name = "getrandom" version = "0.2.6" @@ -1888,6 +1899,21 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.43.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04662ed0e3e5630dfa9b26e4cb823b817f1a9addda855d973a9458c236556244" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + [[package]] name = "windows-sys" version = "0.42.0" diff --git a/Cargo.toml b/Cargo.toml index b23844324..67f557da1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,6 +94,7 @@ tui = "0.19.0" typed-builder = "0.10.0" unicode-segmentation = "1.9.0" unicode-width = "0.1.9" +gethostname = "0.4.1" [target.'cfg(unix)'.dependencies] libc = "0.2.124" diff --git a/sample_configs/default_config.toml b/sample_configs/default_config.toml index 947c8710f..ef5d44285 100644 --- a/sample_configs/default_config.toml +++ b/sample_configs/default_config.toml @@ -61,6 +61,8 @@ #mem_as_value = false # Show tree mode by default in the processes widget. #tree = false +# Set terminal name to hostname +#title_to_hostname = false # Shows an indicator in table widgets tracking where in the list you are. #show_table_scroll_position = false # Show processes as their commands by default in the process widget. diff --git a/src/bin/main.rs b/src/bin/main.rs index 806efe3b4..7c96bc014 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -27,7 +27,7 @@ use bottom::{ use crossterm::{ event::{EnableBracketedPaste, EnableMouseCapture}, execute, - terminal::{enable_raw_mode, EnterAlternateScreen}, + terminal::{enable_raw_mode, EnterAlternateScreen, SetTitle}, }; use tui::{backend::CrosstermBackend, Terminal}; @@ -123,7 +123,8 @@ fn main() -> Result<()> { stdout_val, EnterAlternateScreen, EnableMouseCapture, - EnableBracketedPaste + EnableBracketedPaste, + SetTitle(get_terminal_name(&matches, &config)) )?; enable_raw_mode()?; diff --git a/src/clap.rs b/src/clap.rs index f3333d8c3..4057f9764 100644 --- a/src/clap.rs +++ b/src/clap.rs @@ -338,6 +338,12 @@ use CPU (3) as the default instead. .help("The amount in ms changed upon zooming.") .long_help("The amount of time in milliseconds changed when zooming in/out. The minimum is 1s (1000), and defaults to 15s (15000)."); + let title = Arg::new("title") + .long("title") + .takes_value(true) + .value_name("Title") + .help("Sets the title of the current terminal."); + let tree = Arg::new("tree") .short('T') .long("tree") @@ -410,6 +416,7 @@ use CPU (3) as the default instead. .arg(rate) .arg(regex) .arg(time_delta) + .arg(title) .arg(tree) .arg(network_use_bytes) .arg(network_use_log) diff --git a/src/options.rs b/src/options.rs index d659b00ad..a8b4120a6 100644 --- a/src/options.rs +++ b/src/options.rs @@ -27,6 +27,7 @@ use crate::{ pub mod layout_options; use anyhow::{Context, Result}; +use gethostname::gethostname; #[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct Config { @@ -88,6 +89,7 @@ pub struct ConfigFlags { pub network_use_log: Option, pub network_use_binary_prefix: Option, pub enable_gpu_memory: Option, + pub title_to_hostname: Option, #[serde(with = "humantime_serde")] #[serde(default)] pub retention: Option, @@ -728,6 +730,31 @@ pub fn get_app_use_regex(matches: &ArgMatches, config: &Config) -> bool { false } +pub fn get_terminal_name(matches: &ArgMatches, config: &Config) -> String { + if matches.is_present("title") { + if let Some(custom_name) = matches.value_of("title") { + String::from(custom_name) + } else { + String::from("Bottom") + } + } else if let Some(flags) = &config.flags { + if let Some(title_to_hostname) = flags.title_to_hostname { + if title_to_hostname { + match gethostname().into_string() { + Ok(hostname) => hostname, + Err(_) => String::from("Bottom"), + } + } else { + String::from("Bottom") + } + } else { + String::from("Bottom") + } + } else { + String::from("Bottom") + } +} + fn get_hide_time(matches: &ArgMatches, config: &Config) -> bool { if matches.is_present("hide_time") { return true; From 4d6c136365fe55d73eb97a30df2acb608c2b024e Mon Sep 17 00:00:00 2001 From: RaresCon Date: Mon, 23 Jan 2023 20:25:55 +0200 Subject: [PATCH 5/8] Reworked the feature, now if nothing is used to set the name of the terminal, it will be set as before to its path. This behaviour will happen when an error happens inside the `get_use_terminal_name` function as well. --- src/bin/main.rs | 7 ++++++- src/options.rs | 25 ++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/bin/main.rs b/src/bin/main.rs index 7c96bc014..e1012e89e 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -124,8 +124,13 @@ fn main() -> Result<()> { EnterAlternateScreen, EnableMouseCapture, EnableBracketedPaste, - SetTitle(get_terminal_name(&matches, &config)) )?; + + let use_terminal_name = get_use_terminal_name(&matches, &config); + if use_terminal_name.0 { + execute!(stdout_val, SetTitle(use_terminal_name.1),)?; + } + enable_raw_mode()?; let mut terminal = Terminal::new(CrosstermBackend::new(stdout_val))?; diff --git a/src/options.rs b/src/options.rs index ade9f0bab..5f5443f37 100644 --- a/src/options.rs +++ b/src/options.rs @@ -734,29 +734,24 @@ pub fn get_app_use_regex(matches: &ArgMatches, config: &Config) -> bool { false } -pub fn get_terminal_name(matches: &ArgMatches, config: &Config) -> String { +pub fn get_use_terminal_name(matches: &ArgMatches, config: &Config) -> (bool, String) { if matches.is_present("title") { - if let Some(custom_name) = matches.value_of("title") { - String::from(custom_name) + return if let Some(custom_name) = matches.value_of("title") { + (true, String::from(custom_name)) } else { - String::from("Bottom") - } + (false, String::from("")) + }; } else if let Some(flags) = &config.flags { if let Some(title_to_hostname) = flags.title_to_hostname { if title_to_hostname { - match gethostname().into_string() { - Ok(hostname) => hostname, - Err(_) => String::from("Bottom"), - } - } else { - String::from("Bottom") + return match gethostname().into_string() { + Ok(hostname) => (title_to_hostname, format!("btm ({})", hostname)), + Err(_) => (false, String::from("")), + }; } - } else { - String::from("Bottom") } - } else { - String::from("Bottom") } + (false, String::from("")) } fn get_hide_time(matches: &ArgMatches, config: &Config) -> bool { From 8ced3d1a32f70725745467b5858e467495cd23ca Mon Sep 17 00:00:00 2001 From: RaresCon Date: Tue, 24 Jan 2023 17:28:56 +0200 Subject: [PATCH 6/8] Rebuilt to get `Cargo.lock` generated again --- Cargo.lock | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f45c42e3..05114c476 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -253,7 +253,7 @@ dependencies = [ "unicode-segmentation", "unicode-width", "winapi", - "windows", + "windows 0.44.0", ] [[package]] @@ -765,7 +765,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a329e22866dd78b35d2c639a4a23d7b950aeae300dfd79f4fb19f74055c2404" dependencies = [ "libc", - "windows", + "windows 0.43.0", ] [[package]] @@ -1917,7 +1917,6 @@ version = "0.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04662ed0e3e5630dfa9b26e4cb823b817f1a9addda855d973a9458c236556244" dependencies = [ - "windows-targets", "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", @@ -1927,6 +1926,15 @@ dependencies = [ "windows_x86_64_msvc", ] +[[package]] +name = "windows" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.42.0" From 02d29b7ce915e11b5f7f461980f0c6001c46401e Mon Sep 17 00:00:00 2001 From: RaresCon Date: Fri, 17 Feb 2023 19:00:21 +0200 Subject: [PATCH 7/8] Changed the feature according to the suggestions I removed the custom title option for terminal and made it use the hostname when `--title` is used. The title always contains `btm` now. If `--title` or `title_has_hostname = true` (in config file) is not present, then the terminal has the previous behaviour. --- sample_configs/default_config.toml | 2 +- src/bin/main.rs | 5 ++--- src/clap.rs | 4 +--- src/options.rs | 30 ++++++++++++++---------------- 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/sample_configs/default_config.toml b/sample_configs/default_config.toml index ef5d44285..1c7c7d2ae 100644 --- a/sample_configs/default_config.toml +++ b/sample_configs/default_config.toml @@ -62,7 +62,7 @@ # Show tree mode by default in the processes widget. #tree = false # Set terminal name to hostname -#title_to_hostname = false +#title_has_hostname = false # Shows an indicator in table widgets tracking where in the list you are. #show_table_scroll_position = false # Show processes as their commands by default in the process widget. diff --git a/src/bin/main.rs b/src/bin/main.rs index e1012e89e..769a220d2 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -126,9 +126,8 @@ fn main() -> Result<()> { EnableBracketedPaste, )?; - let use_terminal_name = get_use_terminal_name(&matches, &config); - if use_terminal_name.0 { - execute!(stdout_val, SetTitle(use_terminal_name.1),)?; + if let Some(hostname) = get_use_terminal_name(&matches, &config) { + execute!(stdout_val, SetTitle(hostname),)?; } enable_raw_mode()?; diff --git a/src/clap.rs b/src/clap.rs index 4057f9764..c8a5e766b 100644 --- a/src/clap.rs +++ b/src/clap.rs @@ -340,9 +340,7 @@ use CPU (3) as the default instead. let title = Arg::new("title") .long("title") - .takes_value(true) - .value_name("Title") - .help("Sets the title of the current terminal."); + .help("Sets the title of the current terminal to \"btm ($hostname)\"."); let tree = Arg::new("tree") .short('T') diff --git a/src/options.rs b/src/options.rs index 5f5443f37..f3caac1bf 100644 --- a/src/options.rs +++ b/src/options.rs @@ -93,7 +93,7 @@ pub struct ConfigFlags { pub network_use_log: Option, pub network_use_binary_prefix: Option, pub enable_gpu_memory: Option, - pub title_to_hostname: Option, + pub title_has_hostname: Option, #[serde(with = "humantime_serde")] #[serde(default)] pub retention: Option, @@ -734,24 +734,22 @@ pub fn get_app_use_regex(matches: &ArgMatches, config: &Config) -> bool { false } -pub fn get_use_terminal_name(matches: &ArgMatches, config: &Config) -> (bool, String) { - if matches.is_present("title") { - return if let Some(custom_name) = matches.value_of("title") { - (true, String::from(custom_name)) - } else { - (false, String::from("")) - }; - } else if let Some(flags) = &config.flags { - if let Some(title_to_hostname) = flags.title_to_hostname { - if title_to_hostname { - return match gethostname().into_string() { - Ok(hostname) => (title_to_hostname, format!("btm ({})", hostname)), - Err(_) => (false, String::from("")), - }; +pub fn get_use_terminal_name(matches: &ArgMatches, config: &Config) -> Option { + match gethostname().into_string() { + Ok(hostname) => { + if matches.is_present("title") { + return Some(format!("btm ({})", hostname)); + } else if let Some(flags) = &config.flags { + if let Some(title_has_hostname) = flags.title_has_hostname { + if title_has_hostname { + return Some(format!("btm ({})", hostname)); + } + } } + None } + Err(_) => None, } - (false, String::from("")) } fn get_hide_time(matches: &ArgMatches, config: &Config) -> bool { From 2c3811b311bafc928945c617d36bd5c13b9317cb Mon Sep 17 00:00:00 2001 From: RaresCon Date: Fri, 17 Feb 2023 23:41:21 +0200 Subject: [PATCH 8/8] Resolved some deprecated methods for `arg_matches` --- Cargo.lock | 8 ++-- src/bin/main.rs | 2 +- src/clap.rs | 5 ++- src/lib.rs | 2 +- src/options.rs | 102 ++++++++++++++++++++++++------------------------ 5 files changed, 61 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 05114c476..0d97b54a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -305,9 +305,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.1.12" +version = "3.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c167e37342afc5f33fd87bbc870cedd020d2a6dffa05d45ccd9241fbdd146db" +checksum = "8e538f9ee5aa3b3963f09a997035f883677966ed50fce0292611927ce6f6d8c6" dependencies = [ "atty", "bitflags", @@ -331,9 +331,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.1.1" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "189ddd3b5d32a70b35e7686054371742a937b0d99128e76dde6340210e966669" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" dependencies = [ "os_str_bytes", ] diff --git a/src/bin/main.rs b/src/bin/main.rs index 769a220d2..c83299577 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -42,7 +42,7 @@ fn main() -> Result<()> { check_if_terminal(); // Read from config file. - let config_path = read_config(matches.value_of("config_location")) + let config_path = read_config(matches.get_one::("config_location")) .context("Unable to access the given config file location.")?; let mut config: Config = create_or_get_config(&config_path) .context("Unable to properly parse or create the config file.")?; diff --git a/src/clap.rs b/src/clap.rs index c8a5e766b..94af774dd 100644 --- a/src/clap.rs +++ b/src/clap.rs @@ -1,3 +1,4 @@ +use clap::builder::PossibleValuesParser; use clap::*; const TEMPLATE: &str = "\ @@ -237,14 +238,14 @@ pub fn build_app() -> Command<'static> { .long("color") .takes_value(true) .value_name("COLOR SCHEME") - .possible_values([ + .value_parser(PossibleValuesParser::new([ "default", "default-light", "gruvbox", "gruvbox-light", "nord", "nord-light", - ]) + ])) .hide_possible_values(true) .help("Use a color scheme, use --help for info.") .long_help( diff --git a/src/lib.rs b/src/lib.rs index 7f764e9ca..cc8576f0b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -199,7 +199,7 @@ pub fn handle_key_event_or_break( false } -pub fn read_config(config_location: Option<&str>) -> error::Result> { +pub fn read_config(config_location: Option<&String>) -> error::Result> { let config_path = if let Some(conf_loc) = config_location { Some(PathBuf::from(conf_loc)) } else if cfg!(target_os = "windows") { diff --git a/src/options.rs b/src/options.rs index f3caac1bf..10f3c6900 100644 --- a/src/options.rs +++ b/src/options.rs @@ -500,7 +500,7 @@ pub fn get_widget_layout( } fn get_update_rate_in_milliseconds(matches: &ArgMatches, config: &Config) -> error::Result { - let update_rate_in_milliseconds = if let Some(update_rate) = matches.value_of("rate") { + let update_rate_in_milliseconds = if let Some(update_rate) = matches.get_one::("rate") { update_rate.parse::().map_err(|_| { BottomError::ConfigError( "could not parse as a valid 64-bit unsigned integer".to_string(), @@ -528,11 +528,11 @@ fn get_update_rate_in_milliseconds(matches: &ArgMatches, config: &Config) -> err fn get_temperature( matches: &ArgMatches, config: &Config, ) -> error::Result { - if matches.is_present("fahrenheit") { + if matches.contains_id("fahrenheit") { return Ok(data_harvester::temperature::TemperatureType::Fahrenheit); - } else if matches.is_present("kelvin") { + } else if matches.contains_id("kelvin") { return Ok(data_harvester::temperature::TemperatureType::Kelvin); - } else if matches.is_present("celsius") { + } else if matches.contains_id("celsius") { return Ok(data_harvester::temperature::TemperatureType::Celsius); } else if let Some(flags) = &config.flags { if let Some(temp_type) = &flags.temperature_type { @@ -553,7 +553,7 @@ fn get_temperature( /// Yes, this function gets whether to show average CPU (true) or not (false) fn get_show_average_cpu(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("hide_avg_cpu") { + if matches.contains_id("hide_avg_cpu") { return false; } else if let Some(flags) = &config.flags { if let Some(avg_cpu) = flags.hide_avg_cpu { @@ -565,7 +565,7 @@ fn get_show_average_cpu(matches: &ArgMatches, config: &Config) -> bool { } fn get_use_dot(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("dot_marker") { + if matches.contains_id("dot_marker") { return true; } else if let Some(flags) = &config.flags { if let Some(dot_marker) = flags.dot_marker { @@ -576,7 +576,7 @@ fn get_use_dot(matches: &ArgMatches, config: &Config) -> bool { } fn get_use_left_legend(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("left_legend") { + if matches.contains_id("left_legend") { return true; } else if let Some(flags) = &config.flags { if let Some(left_legend) = flags.left_legend { @@ -588,7 +588,7 @@ fn get_use_left_legend(matches: &ArgMatches, config: &Config) -> bool { } fn get_use_current_cpu_total(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("current_usage") { + if matches.contains_id("current_usage") { return true; } else if let Some(flags) = &config.flags { if let Some(current_usage) = flags.current_usage { @@ -600,7 +600,7 @@ fn get_use_current_cpu_total(matches: &ArgMatches, config: &Config) -> bool { } fn get_unnormalized_cpu(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("unnormalized_cpu") { + if matches.contains_id("unnormalized_cpu") { return true; } else if let Some(flags) = &config.flags { if let Some(unnormalized_cpu) = flags.unnormalized_cpu { @@ -612,7 +612,7 @@ fn get_unnormalized_cpu(matches: &ArgMatches, config: &Config) -> bool { } fn get_use_basic_mode(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("basic") { + if matches.contains_id("basic") { return true; } else if let Some(flags) = &config.flags { if let Some(basic) = flags.basic { @@ -627,21 +627,22 @@ fn get_use_basic_mode(matches: &ArgMatches, config: &Config) -> bool { fn get_default_time_value( matches: &ArgMatches, config: &Config, retention_ms: u64, ) -> error::Result { - let default_time = if let Some(default_time_value) = matches.value_of("default_time_value") { - default_time_value.parse::().map_err(|_| { - BottomError::ConfigError( - "could not parse as a valid 64-bit unsigned integer".to_string(), - ) - })? - } else if let Some(flags) = &config.flags { - if let Some(default_time_value) = flags.default_time_value { - default_time_value + let default_time = + if let Some(default_time_value) = matches.get_one::("default_time_value") { + default_time_value.parse::().map_err(|_| { + BottomError::ConfigError( + "could not parse as a valid 64-bit unsigned integer".to_string(), + ) + })? + } else if let Some(flags) = &config.flags { + if let Some(default_time_value) = flags.default_time_value { + default_time_value + } else { + DEFAULT_TIME_MILLISECONDS + } } else { DEFAULT_TIME_MILLISECONDS - } - } else { - DEFAULT_TIME_MILLISECONDS - }; + }; if default_time < 30000 { return Err(BottomError::ConfigError( @@ -660,7 +661,7 @@ fn get_default_time_value( fn get_time_interval( matches: &ArgMatches, config: &Config, retention_ms: u64, ) -> error::Result { - let time_interval = if let Some(time_interval) = matches.value_of("time_delta") { + let time_interval = if let Some(time_interval) = matches.get_one::("time_delta") { time_interval.parse::().map_err(|_| { BottomError::ConfigError( "could not parse as a valid 64-bit unsigned integer".to_string(), @@ -691,7 +692,7 @@ fn get_time_interval( } pub fn get_app_grouping(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("group") { + if matches.contains_id("group") { return true; } else if let Some(flags) = &config.flags { if let Some(grouping) = flags.group_processes { @@ -702,7 +703,7 @@ pub fn get_app_grouping(matches: &ArgMatches, config: &Config) -> bool { } pub fn get_app_case_sensitive(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("case_sensitive") { + if matches.contains_id("case_sensitive") { return true; } else if let Some(flags) = &config.flags { if let Some(case_sensitive) = flags.case_sensitive { @@ -713,7 +714,7 @@ pub fn get_app_case_sensitive(matches: &ArgMatches, config: &Config) -> bool { } pub fn get_app_match_whole_word(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("whole_word") { + if matches.contains_id("whole_word") { return true; } else if let Some(flags) = &config.flags { if let Some(whole_word) = flags.whole_word { @@ -724,7 +725,7 @@ pub fn get_app_match_whole_word(matches: &ArgMatches, config: &Config) -> bool { } pub fn get_app_use_regex(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("regex") { + if matches.contains_id("regex") { return true; } else if let Some(flags) = &config.flags { if let Some(regex) = flags.regex { @@ -737,7 +738,7 @@ pub fn get_app_use_regex(matches: &ArgMatches, config: &Config) -> bool { pub fn get_use_terminal_name(matches: &ArgMatches, config: &Config) -> Option { match gethostname().into_string() { Ok(hostname) => { - if matches.is_present("title") { + if matches.contains_id("title") { return Some(format!("btm ({})", hostname)); } else if let Some(flags) = &config.flags { if let Some(title_has_hostname) = flags.title_has_hostname { @@ -753,7 +754,7 @@ pub fn get_use_terminal_name(matches: &ArgMatches, config: &Config) -> Option bool { - if matches.is_present("hide_time") { + if matches.contains_id("hide_time") { return true; } else if let Some(flags) = &config.flags { if let Some(hide_time) = flags.hide_time { @@ -764,7 +765,7 @@ fn get_hide_time(matches: &ArgMatches, config: &Config) -> bool { } fn get_autohide_time(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("autohide_time") { + if matches.contains_id("autohide_time") { return true; } else if let Some(flags) = &config.flags { if let Some(autohide_time) = flags.autohide_time { @@ -776,7 +777,7 @@ fn get_autohide_time(matches: &ArgMatches, config: &Config) -> bool { } fn get_expanded_on_startup(matches: &ArgMatches, config: &Config) -> bool { - matches.is_present("expanded_on_startup") + matches.contains_id("expanded_on_startup") || config .flags .as_ref() @@ -787,7 +788,7 @@ fn get_expanded_on_startup(matches: &ArgMatches, config: &Config) -> bool { fn get_default_widget_and_count( matches: &ArgMatches, config: &Config, ) -> error::Result<(Option, u64)> { - let widget_type = if let Some(widget_type) = matches.value_of("default_widget_type") { + let widget_type = if let Some(widget_type) = matches.get_one::("default_widget_type") { let parsed_widget = widget_type.parse::()?; if let BottomWidgetType::Empty = parsed_widget { None @@ -809,7 +810,8 @@ fn get_default_widget_and_count( None }; - let widget_count = if let Some(widget_count) = matches.value_of("default_widget_count") { + let widget_count = if let Some(widget_count) = matches.get_one::("default_widget_count") + { Some(widget_count.parse::()?) } else if let Some(flags) = &config.flags { flags @@ -835,7 +837,7 @@ fn get_default_widget_and_count( } fn get_disable_click(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("disable_click") { + if matches.contains_id("disable_click") { return true; } else if let Some(flags) = &config.flags { if let Some(disable_click) = flags.disable_click { @@ -846,7 +848,7 @@ fn get_disable_click(matches: &ArgMatches, config: &Config) -> bool { } fn get_use_old_network_legend(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("use_old_network_legend") { + if matches.contains_id("use_old_network_legend") { return true; } else if let Some(flags) = &config.flags { if let Some(use_old_network_legend) = flags.use_old_network_legend { @@ -857,7 +859,7 @@ fn get_use_old_network_legend(matches: &ArgMatches, config: &Config) -> bool { } fn get_hide_table_gap(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("hide_table_gap") { + if matches.contains_id("hide_table_gap") { return true; } else if let Some(flags) = &config.flags { if let Some(hide_table_gap) = flags.hide_table_gap { @@ -878,7 +880,7 @@ fn get_use_battery(matches: &ArgMatches, config: &Config) -> bool { } if cfg!(feature = "battery") { - if matches.is_present("battery") { + if matches.contains_id("battery") { return true; } else if let Some(flags) = &config.flags { if let Some(battery) = flags.battery { @@ -891,7 +893,7 @@ fn get_use_battery(matches: &ArgMatches, config: &Config) -> bool { fn get_enable_gpu_memory(matches: &ArgMatches, config: &Config) -> bool { if cfg!(feature = "gpu") { - if matches.is_present("enable_gpu_memory") { + if matches.contains_id("enable_gpu_memory") { return true; } else if let Some(flags) = &config.flags { if let Some(enable_gpu_memory) = flags.enable_gpu_memory { @@ -904,7 +906,7 @@ fn get_enable_gpu_memory(matches: &ArgMatches, config: &Config) -> bool { #[allow(dead_code)] fn get_no_write(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("no_write") { + if matches.contains_id("no_write") { return true; } else if let Some(flags) = &config.flags { if let Some(no_write) = flags.no_write { @@ -952,7 +954,7 @@ fn get_ignore_list(ignore_list: &Option) -> error::Result error::Result { - if let Some(color) = matches.value_of("color") { + if let Some(color) = matches.get_one::("color") { // Highest priority is always command line flags... return ColourScheme::from_str(color); } else if let Some(colors) = &config.colors { @@ -977,7 +979,7 @@ pub fn get_color_scheme(matches: &ArgMatches, config: &Config) -> error::Result< } fn get_mem_as_value(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("mem_as_value") { + if matches.contains_id("mem_as_value") { return true; } else if let Some(flags) = &config.flags { if let Some(mem_as_value) = flags.mem_as_value { @@ -988,7 +990,7 @@ fn get_mem_as_value(matches: &ArgMatches, config: &Config) -> bool { } fn get_is_default_tree(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("tree") { + if matches.contains_id("tree") { return true; } else if let Some(flags) = &config.flags { if let Some(tree) = flags.tree { @@ -999,7 +1001,7 @@ fn get_is_default_tree(matches: &ArgMatches, config: &Config) -> bool { } fn get_show_table_scroll_position(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("show_table_scroll_position") { + if matches.contains_id("show_table_scroll_position") { return true; } else if let Some(flags) = &config.flags { if let Some(show_table_scroll_position) = flags.show_table_scroll_position { @@ -1010,7 +1012,7 @@ fn get_show_table_scroll_position(matches: &ArgMatches, config: &Config) -> bool } fn get_is_default_process_command(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("process_command") { + if matches.contains_id("process_command") { return true; } else if let Some(flags) = &config.flags { if let Some(process_command) = flags.process_command { @@ -1021,7 +1023,7 @@ fn get_is_default_process_command(matches: &ArgMatches, config: &Config) -> bool } fn get_is_advanced_kill_disabled(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("disable_advanced_kill") { + if matches.contains_id("disable_advanced_kill") { return true; } else if let Some(flags) = &config.flags { if let Some(disable_advanced_kill) = flags.disable_advanced_kill { @@ -1032,7 +1034,7 @@ fn get_is_advanced_kill_disabled(matches: &ArgMatches, config: &Config) -> bool } fn get_network_unit_type(matches: &ArgMatches, config: &Config) -> DataUnit { - if matches.is_present("network_use_bytes") { + if matches.contains_id("network_use_bytes") { return DataUnit::Byte; } else if let Some(flags) = &config.flags { if let Some(network_use_bytes) = flags.network_use_bytes { @@ -1046,7 +1048,7 @@ fn get_network_unit_type(matches: &ArgMatches, config: &Config) -> DataUnit { } fn get_network_scale_type(matches: &ArgMatches, config: &Config) -> AxisScaling { - if matches.is_present("network_use_log") { + if matches.contains_id("network_use_log") { return AxisScaling::Log; } else if let Some(flags) = &config.flags { if let Some(network_use_log) = flags.network_use_log { @@ -1060,7 +1062,7 @@ fn get_network_scale_type(matches: &ArgMatches, config: &Config) -> AxisScaling } fn get_network_use_binary_prefix(matches: &ArgMatches, config: &Config) -> bool { - if matches.is_present("network_use_binary_prefix") { + if matches.contains_id("network_use_binary_prefix") { return true; } else if let Some(flags) = &config.flags { if let Some(network_use_binary_prefix) = flags.network_use_binary_prefix { @@ -1073,7 +1075,7 @@ fn get_network_use_binary_prefix(matches: &ArgMatches, config: &Config) -> bool fn get_retention_ms(matches: &ArgMatches, config: &Config) -> error::Result { const DEFAULT_RETENTION_MS: u64 = 600 * 1000; // Keep 10 minutes of data. - if let Some(retention) = matches.value_of("retention") { + if let Some(retention) = matches.get_one::("retention") { humantime::parse_duration(retention) .map(|dur| dur.as_millis() as u64) .map_err(|err| BottomError::ConfigError(format!("invalid retention duration: {err:?}")))