summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClement Tsang <34804052+ClementTsang@users.noreply.github.com>2024-01-10 19:07:22 -0500
committerGitHub <noreply@github.com>2024-01-10 19:07:22 -0500
commit6b6217655479df639c9ad7f6324939eae4f81cea (patch)
treeb04542fb162a4daa443118520af8809cdb4855d0
parent0f969fcfd4409f8045357298c5229500cf720cba (diff)
refactor: rearrange/resort args (#1376)
* clean up Cargo.toml * some small cleanup * refactor: group together similar args in the help generation and code This groups together related arguments in both the help text and the code itself. * update changelog * clippy * builder pattern instead
-rw-r--r--CHANGELOG.md3
-rw-r--r--Cargo.lock16
-rw-r--r--Cargo.toml25
-rw-r--r--build.rs7
-rw-r--r--src/options/args.rs900
-rw-r--r--src/options/args.template8
6 files changed, 562 insertions, 397 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2227e9d6..5ecab8bc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,7 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changes
-- [#1344](https://github.com/ClementTsang/bottom/pull/1344): Change the `group` command line argument to `group_processes` for consistency with the config file option.
+- [#1344](https://github.com/ClementTsang/bottom/pull/1344): Change the `group` command line-argument to `group_processes` for consistency with the config file option.
+- [#1376](https://github.com/ClementTsang/bottom/pull/1376): Group together related command-line arguments in `-h` and `--help`.
### Bug Fixes
diff --git a/Cargo.lock b/Cargo.lock
index 1dd09a57..30e79e1a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -239,18 +239,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
-version = "4.4.11"
+version = "4.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2"
+checksum = "33e92c5c1a78c62968ec57dbc2440366a2d6e5a23faf829970ff1585dc6b18e2"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
-version = "4.4.11"
+version = "4.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb"
+checksum = "f4323769dc8a61e2c39ad7dc26f6f2800524691a44d74fe3d1071a5c24db6370"
dependencies = [
"anstream",
"anstyle",
@@ -261,9 +261,9 @@ dependencies = [
[[package]]
name = "clap_complete"
-version = "4.4.5"
+version = "4.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a51919c5608a32e34ea1d6be321ad070065e17613e168c5b6977024290f2630b"
+checksum = "97aeaa95557bd02f23fbb662f981670c3d20c5a26e69f7354b28f57092437fcd"
dependencies = [
"clap",
]
@@ -296,9 +296,9 @@ checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
[[package]]
name = "clap_mangen"
-version = "0.2.15"
+version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3be86020147691e1d2ef58f75346a3d4d94807bfc473e377d52f09f0f7d77f7"
+checksum = "10b5db60b3310cdb376fbeb8826e875a38080d0c61bdec0a91a3da8338948736"
dependencies = [
"clap",
"roff",
diff --git a/Cargo.toml b/Cargo.toml
index 883a9fb3..20dbdf00 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -64,23 +64,20 @@ strip = false
[features]
battery = ["starship-battery"]
-gpu = ["nvidia"]
nvidia = ["nvml-wrapper"]
+gpu = ["nvidia"]
zfs = []
-# Including logging for debugging purposes.
+# Logging for debugging performance.
logging = ["fern", "log", "time/local-offset"]
-# The features we use on deploy. Logging is not included as that is primarily (for now) just for debugging locally.
-deploy = ["battery", "gpu", "zfs"]
-
-default = ["deploy"]
+default = ["battery", "gpu", "zfs"]
[dependencies]
anyhow = "1.0.75"
backtrace = "0.3.69"
cfg-if = "1.0.0"
-clap = { version = "4.4.11", features = ["default", "cargo", "wrap_help"] }
+clap = { version = "4.4.14", features = ["default", "cargo", "wrap_help"] }
concat-string = "1.0.1"
crossterm = "0.27.0"
ctrlc = { version = "3.4.1", features = ["termination"] }
@@ -93,7 +90,9 @@ indexmap = "2.1.0"
itertools = "0.12.0"
kstring = { version = "2.0.0", features = ["arc"] }
log = { version = "0.4.20", optional = true }
-nvml-wrapper = { version = "0.9.0", optional = true, features = ["legacy-functions"] }
+nvml-wrapper = { version = "0.9.0", optional = true, features = [
+ "legacy-functions",
+] }
regex = "1.10.2"
serde = { version = "=1.0.193", features = ["derive"] }
starship-battery = { version = "0.8.2", optional = true }
@@ -133,15 +132,17 @@ filedescriptor = "0.8.2"
[dev-dependencies]
assert_cmd = "2.0.12"
-cargo-husky = { version = "1.5.0", default-features = false, features = ["user-hooks"] }
+cargo-husky = { version = "1.5.0", default-features = false, features = [
+ "user-hooks",
+] }
predicates = "3.0.3"
[build-dependencies]
-clap = { version = "4.4.11", features = ["default", "cargo", "wrap_help"] }
-clap_complete = "4.4.5"
+clap = { version = "4.4.14", features = ["default", "cargo", "wrap_help"] }
+clap_complete = "4.4.6"
clap_complete_fig = "4.4.2"
clap_complete_nushell = "4.4.2"
-clap_mangen = "0.2.15"
+clap_mangen = "0.2.16"
[package.metadata.deb]
section = "utility"
diff --git a/build.rs b/build.rs
index 1d13c701..5ebf6155 100644
--- a/build.rs
+++ b/build.rs
@@ -1,13 +1,18 @@
+#[allow(dead_code)]
+#[path = "src/options/args.rs"]
+mod args;
+
use std::{
env, fs, io,
path::{Path, PathBuf},
};
+use clap::Command;
use clap_complete::{generate_to, shells::Shell, Generator};
use clap_complete_fig::Fig;
use clap_complete_nushell::Nushell;
-include!("src/options/args.rs");
+use crate::args::build_app;
fn create_dir(dir: &Path) -> io::Result<()> {
let res = fs::create_dir_all(dir);
diff --git a/src/options/args.rs b/src/options/args.rs
index 2c524da8..30fe88c9 100644
--- a/src/options/args.rs
+++ b/src/options/args.rs
@@ -1,16 +1,9 @@
-use clap::{builder::PossibleValuesParser, *};
-
-const TEMPLATE: &str = "\
-{name} {version}
-{author}
-
-{about}
-
-{usage-heading} {usage}
+//! Argument parsing via clap.
+//!
+//! Note that you probably want to keep this as a single file so the build script doesn't
+//! trip all over itself.
-{all-args}";
-
-const USAGE: &str = "btm [OPTIONS]";
+use clap::{builder::PossibleValuesParser, *};
const DEFAULT_WIDGET_TYPE_STR: &str = {
#[cfg(feature = "battery")]
@@ -87,191 +80,236 @@ pub fn get_matches() -> ArgMatches {
build_app().get_matches()
}
-pub fn build_app() -> Command {
- // Temps
- let kelvin = Arg::new("kelvin")
- .short('k')
- .long("kelvin")
- .action(ArgAction::SetTrue)
- .help("Sets the temperature type to Kelvin.")
- .long_help("Sets the temperature type to Kelvin.");
-
- let fahrenheit = Arg::new("fahrenheit")
- .short('f')
- .long("fahrenheit")
- .action(ArgAction::SetTrue)
- .help("Sets the temperature type to Fahrenheit.")
- .long_help("Sets the temperature type to Fahrenheit.");
-
- let celsius = Arg::new("celsius")
- .short('c')
- .long("celsius")
- .action(ArgAction::SetTrue)
- .help("Sets the temperature type to Celsius.")
- .long_help("Sets the temperature type to Celsius. This is the default option.");
-
- // All flags. These are in alphabetical order
- let autohide_time = Arg::new("autohide_time")
- .long("autohide_time")
- .action(ArgAction::SetTrue)
- .help("Temporarily shows the time scale in graphs.")
- .long_help(
- "Automatically hides the time scale in graphs after being shown for \
- a brief moment when zoomed in/out. If time is disabled via --hide_time \
- then this will have no effect.",
- );
+trait CommandBuilder {
+ fn general_args(self) -> Self;
- let basic = Arg::new("basic")
- .short('b')
- .long("basic")
- .action(ArgAction::SetTrue)
- .help("Hides graphs and uses a more basic look.")
- .long_help(
- "Hides graphs and uses a more basic look. Design is largely inspired by htop's.",
- );
+ fn style_args(self) -> Self;
- let case_sensitive = Arg::new("case_sensitive")
- .short('S')
- .long("case_sensitive")
- .action(ArgAction::SetTrue)
- .help("Enables case sensitivity by default.")
- .long_help("When searching for a process, enables case sensitivity by default.");
-
- let current_usage = Arg::new("current_usage")
- .short('u')
- .long("current_usage")
- .action(ArgAction::SetTrue)
- .help("Sets process CPU% to be based on current CPU%.")
- .long_help("Sets process CPU% usage to be based on the current system CPU% usage rather than total CPU usage.");
-
- let unnormalized_cpu = Arg::new("unnormalized_cpu")
- .short('n')
- .long("unnormalized_cpu")
- .action(ArgAction::SetTrue)
- .help("Show process CPU% usage without normalizing over the number of cores.")
- .long_help(
- "Shows all process CPU% usage without averaging over the number of CPU cores in the system.",
- );
+ fn temperature_args(self) -> Self;
- let disable_click = Arg::new("disable_click")
- .long("disable_click")
- .action(ArgAction::SetTrue)
- .help("Disables mouse clicks.")
- .long_help("Disables mouse clicks from interacting with the program.");
-
- let dot_marker = Arg::new("dot_marker")
- .short('m')
- .long("dot_marker")
- .action(ArgAction::SetTrue)
- .help("Uses a dot marker for graphs.")
- .long_help("Uses a dot marker for graphs as opposed to the default braille marker.");
-
- let group_processes = Arg::new("group_processes")
- .short('g')
- .long("group_processes")
- .action(ArgAction::SetTrue)
- .help("Groups processes with the same name by default.")
- .long_help("Groups processes with the same name by default.");
-
- let hide_avg_cpu = Arg::new("hide_avg_cpu")
- .short('a')
- .long("hide_avg_cpu")
- .action(ArgAction::SetTrue)
- .help("Hides the average CPU usage.")
- .long_help("Hides the average CPU usage from being shown.");
-
- let hide_table_gap = Arg::new("hide_table_gap")
- .long("hide_table_gap")
- .action(ArgAction::SetTrue)
- .help("Hides spacing between table headers and entries.")
- .long_help("Hides the spacing between table headers and entries.");
-
- let hide_time = Arg::new("hide_time")
- .long("hide_time")
- .action(ArgAction::SetTrue)
- .help("Hides the time scale.")
- .long_help("Completely hides the time scale from being shown.");
-
- let process_command = Arg::new("process_command")
- .long("process_command")
- .action(ArgAction::SetTrue)
- .help("Show processes as their commands by default.")
- .long_help("Show processes as their commands by default in the process widget.");
-
- let left_legend = Arg::new("left_legend")
- .short('l')
- .long("left_legend")
- .action(ArgAction::SetTrue)
- .help("Puts the CPU chart legend to the left side.")
- .long_help("Puts the CPU chart legend to the left side rather than the right side.");
-
- let regex = Arg::new("regex")
- .short('R')
- .long("regex")
- .action(ArgAction::SetTrue)
- .help("Enables regex by default.")
- .long_help("When searching for a process, enables regex by default.");
-
- let disable_advanced_kill = Arg::new("disable_advanced_kill")
- .long("disable_advanced_kill")
- .action(ArgAction::SetTrue)
- .help("Hides advanced process killing.")
- .long_help("Hides advanced options to stop a process on Unix-like systems. The only option shown is 15 (TERM).");
-
- let show_table_scroll_position = Arg::new("show_table_scroll_position")
- .long("show_table_scroll_position")
- .action(ArgAction::SetTrue)
- .help("Shows the scroll position tracker in table widgets.")
- .long_help("Shows the list scroll position tracker in the widget title for table widgets.");
-
- let use_old_network_legend = Arg::new("use_old_network_legend")
- .long("use_old_network_legend")
- .action(ArgAction::SetTrue)
- .help("DEPRECATED - uses a separate network legend.")
- .long_help(
- "DEPRECATED - uses an older (pre-0.4), separate network widget legend. This display is not \
- tested anymore and could be broken.",
- );
+ fn process_args(self) -> Self;
- let whole_word = Arg::new("whole_word")
- .short('W')
- .long("whole_word")
- .action(ArgAction::SetTrue)
- .help("Enables whole-word matching by default.")
- .long_help(
- "When searching for a process, return results that match the entire query by default.",
- );
+ fn cpu_args(self) -> Self;
+
+ fn mem_args(self) -> Self;
+
+ fn network_args(self) -> Self;
+
+ fn battery_args(self) -> Self;
+
+ fn gpu_args(self) -> Self;
+
+ fn other(self) -> Self;
+}
+
+impl CommandBuilder for Command {
+ fn general_args(self) -> Command {
+ const HEADING: &str = "General Options";
+
+ let autohide_time = Arg::new("autohide_time")
+ .long("autohide_time")
+ .action(ArgAction::SetTrue)
+ .help("Temporarily shows the time scale in graphs.")
+ .long_help(
+ "Automatically hides the time scale in graphs after being shown for \
+ a brief moment when zoomed in/out. If time is disabled via --hide_time \
+ then this will have no effect.",
+ )
+ .help_heading(HEADING);
+
+ let basic = Arg::new("basic")
+ .short('b')
+ .long("basic")
+ .action(ArgAction::SetTrue)
+ .help("Hides graphs and uses a more basic look.")
+ .long_help(
+ "Hides graphs and uses a more basic look. Design is largely inspired by htop's.",
+ )
+ .help_heading(HEADING);
+
+ let disable_click = Arg::new("disable_click")
+ .long("disable_click")
+ .action(ArgAction::SetTrue)
+ .help("Disables mouse clicks.")
+ .long_help("Disables mouse clicks from interacting with the program.")
+ .help_heading(HEADING);
+
+ let dot_marker = Arg::new("dot_marker")
+ .short('m')
+ .long("dot_marker")
+ .action(ArgAction::SetTrue)
+ .help("Uses a dot marker for graphs.")
+ .long_help("Uses a dot marker for graphs as opposed to the default braille marker.")
+ .help_heading(HEADING);
+
+ let hide_table_gap = Arg::new("hide_table_gap")
+ .long("hide_table_gap")
+ .action(ArgAction::SetTrue)
+ .help("Hides spacing between table headers and entries.")
+ .long_help("Hides the spacing between table headers and entries.")
+ .help_heading(HEADING);
+
+ let hide_time = Arg::new("hide_time")
+ .long("hide_time")
+ .action(ArgAction::SetTrue)
+ .help("Hides the time scale.")
+ .long_help("Completely hides the time scale from being shown.")
+ .help_heading(HEADING);
+
+ let left_legend = Arg::new("left_legend")
+ .short('l')
+ .long("left_legend")
+ .action(ArgAction::SetTrue)
+ .help("Puts the CPU chart legend to the left side.")
+ .long_help("Puts the CPU chart legend to the left side rather than the right side.")
+ .help_heading(HEADING);
+
+ let show_table_scroll_position = Arg::new("show_table_scroll_position")
+ .long("show_table_scroll_position")
+ .action(ArgAction::SetTrue)
+ .help("Shows the scroll position tracker in table widgets.")
+ .long_help(
+ "Shows the list scroll position tracker in the widget title for table widgets.",
+ )
+ .help_heading(HEADING);
+
+ let config_location = Arg::new("config_location")
+ .short('C')
+ .long("config")
+ .action(ArgAction::Set)
+ .value_name("CONFIG PATH")
+ .help("Sets the location of the config file.")
+ .long_help(
+ "Sets the location of the config file. Expects a config file in the TOML format. \
+ If it doesn't exist, one is created.",
+ )
+ .value_hint(ValueHint::AnyPath)
+ .help_heading(HEADING);
+
+ let default_time_value = Arg::new("default_time_value")
+ .short('t')
+ .long("default_time_value")
+ .action(ArgAction::Set)
+ .value_name("TIME")
+ .help("Default time value for graphs.")
+ .long_help(
+ "Default time value for graphs. Takes a number in milliseconds or a human duration (e.g. 60s). The minimum time is 30s, and the default is 60s.",
+ )
+ .help_heading(HEADING);
+
+ // TODO: Charts are broken in the manpage
+ let default_widget_count = Arg::new("default_widget_count")
+ .long("default_widget_count")
+ .action(ArgAction::Set)
+ .requires_all(["default_widget_type"])
+ .value_name("INT")
+ .help("Sets the n'th selected widget type as the default.")
+ .long_help(
+ "\
+Sets the n'th selected widget type to use as the default widget.
+Requires 'default_widget_type' to also be set, and defaults to 1.
+
+This reads from left to right, top to bottom. For example, suppose
+we have a layout that looks like:
++-------------------+-----------------------+
+| CPU (1) | CPU (2) |
++---------+---------+-------------+---------+
+| Process | CPU (3) | Temperature | CPU (4) |
++---------+---------+-------------+---------+
- // All options. Again, alphabetical order.
- let config_location = Arg::new("config_location")
- .short('C')
- .long("config")
- .action(ArgAction::Set)
- .value_name("CONFIG PATH")
- .help("Sets the location of the config file.")
- .long_help(
- "Sets the location of the config file. Expects a config file in the TOML format. \
- If it doesn't exist, one is created.",
- )
- .value_hint(ValueHint::AnyPath);
-
- // TODO: File an issue with manpage, it cannot render charts correctly.
- let color = Arg::new("color")
- .long("color")
- .action(ArgAction::Set)
- .value_name("COLOR SCHEME")
- .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(
- "\
+And we set our default widget type to 'CPU'. If we set
+'--default_widget_count 1', then it would use the CPU (1) as
+the default widget. If we set '--default_widget_count 3', it would
+use CPU (3) as the default instead.
+ ",
+ )
+ .help_heading(HEADING);
+
+ let default_widget_type = Arg::new("default_widget_type")
+ .long("default_widget_type")
+ .action(ArgAction::Set)
+ .value_name("WIDGET TYPE")
+ .help("Sets the default widget type, use --help for info.")
+ .long_help(DEFAULT_WIDGET_TYPE_STR)
+ .help_heading(HEADING);
+
+ let expanded_on_startup = Arg::new("expanded_on_startup")
+ .short('e')
+ .long("expanded")
+ .action(ArgAction::SetTrue)
+ .help("Expand the default widget upon starting the app.")
+ .long_help("Expand the default widget upon starting the app. Same as pressing \"e\" inside the app. Use with \"default_widget_type\" and \"default_widget_count\" to select desired expanded widget. This flag has no effect in basic mode (--basic)")
+ .help_heading(HEADING);
+
+ let rate = Arg::new("rate")
+ .short('r')
+ .long("rate")
+ .action(ArgAction::Set)
+ .value_name("TIME")
+ .help("Sets the data refresh rate.")
+ .long_help("Sets the data refresh rate. Takes a number in milliseconds or a human duration (e.g. 5s). The minimum is 250ms, and defaults to 1000ms. Smaller values may take more computer resources.")
+ .help_heading(HEADING);
+
+ let time_delta = Arg::new("time_delta")
+ .short('d')
+ .long("time_delta")
+ .action(ArgAction::Set)
+ .value_name("TIME")
+ .help("The amount of time changed upon zooming.")
+ .long_help("The amount of time changed when zooming in/out. Takes a number in milliseconds or a human duration (e.g. 30s). The minimum is 1s, and defaults to 15s.")
+ .help_heading(HEADING);
+
+ let retention = Arg::new("retention")
+ .long("retention")
+ .action(ArgAction::Set)
+ .value_name("TIME")
+ .help("The timespan of data stored.")
+ .long_help("How much data is stored at once in terms of time. Takes a number in milliseconds or a human duration (e.g. 20m), with a minimum of 1 minute. Note higher values will take up more memory. Defaults to 10 minutes.")
+ .help_heading(HEADING);
+
+ let mut args = [
+ autohide_time,
+ basic,
+ disable_click,
+ dot_marker,
+ hide_table_gap,
+ hide_time,
+ left_legend,
+ show_table_scroll_position,
+ config_location,
+ default_time_value,
+ default_widget_count,
+ default_widget_type,
+ expanded_on_startup,
+ rate,
+ time_delta,
+ retention,
+ ];
+ args.sort_unstable();
+
+ self.args(args)
+ }
+
+ fn style_args(self) -> Command {
+ const HEADING: &str = "Style Options";
+
+ // TODO: File an issue with manpage, it cannot render charts correctly.
+ let color = Arg::new("color")
+ .long("color")
+ .action(ArgAction::Set)
+ .value_name("COLOR SCHEME")
+ .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(
+ "\
Use a pre-defined color scheme. Currently supported values are:
+------------------------------------------------------------+
| default |
@@ -287,214 +325,315 @@ Use a pre-defined color scheme. Currently supported values are:
| nord-light (nord but for use with light backgrounds) |
+------------------------------------------------------------+
Defaults to \"default\".
-",
- );
+ ",
+ )
+ .help_heading(HEADING);
- let mem_as_value = Arg::new("mem_as_value")
- .long("mem_as_value")
- .action(ArgAction::SetTrue)
- .help("Defaults to showing process memory usage by value.")
- .long_help("Defaults to showing process memory usage by value. Otherwise, it defaults to showing it by percentage.");
-
- let default_time_value = Arg::new("default_time_value")
- .short('t')
- .long("default_time_value")
- .action(ArgAction::Set)
- .value_name("TIME")
- .help("Default time value for graphs.")
- .long_help(
- "Default time value for graphs. Takes a number in milliseconds or a human duration (e.g. 60s). The minimum time is 30s, and the default is 60s.",
- );
+ self.arg(color)
+ }
- // TODO: Charts are broken in the manpage
- let default_widget_count = Arg::new("default_widget_count")
- .long("default_widget_count")
- .action(ArgAction::Set)
- .requires_all(["default_widget_type"])
- .value_name("INT")
- .help("Sets the n'th selected widget type as the default.")
- .long_help(
- "\
-Sets the n'th selected widget type to use as the default widget.
-Requires 'default_widget_type' to also be set, and defaults to 1.
+ fn temperature_args(self) -> Command {
+ const HEADING: &str = "Temperature Options";
+
+ let celsius = Arg::new("celsius")
+ .short('c')
+ .long("celsius")
+ .action(ArgAction::SetTrue)
+ .help("Use Celsius as the temperature unit.")
+ .long_help("Use Celsius as the temperature unit. This is the default option.")
+ .help_heading(HEADING);
+
+ let fahrenheit = Arg::new("fahrenheit")
+ .short('f')
+ .long("fahrenheit")
+ .action(ArgAction::SetTrue)
+ .help("Use Fahrenheit as the temperature unit.")
+ .help_heading(HEADING);
+
+ let kelvin = Arg::new("kelvin")
+ .short('k')
+ .long("kelvin")
+ .action(ArgAction::SetTrue)
+ .help("Use Kelvin as the temperature unit.")
+ .help_heading(HEADING);
+
+ let temperature_group = ArgGroup::new("TEMPERATURE_TYPE").args([
+ celsius.get_id(),
+ fahrenheit.get_id(),
+ kelvin.get_id(),
+ ]);
+
+ let args = [celsius, fahrenheit, kelvin];
+
+ self.args(args).group(temperature_group)
+ }
-This reads from left to right, top to bottom. For example, suppose
-we have a layout that looks like:
-+-------------------+-----------------------+
-| CPU (1) | CPU (2) |
-+---------+---------+-------------+---------+
-| Process | CPU (3) | Temperature | CPU (4) |
-+---------+---------+-------------+---------+
+ fn process_args(self) -> Command {
+ const HEADING: &str = "Process Options";
+
+ let case_sensitive = Arg::new("case_sensitive")
+ .short('S')
+ .long("case_sensitive")
+ .action(ArgAction::SetTrue)
+ .help("Enables case sensitivity by default.")
+ .long_help("When searching for a process, enables case sensitivity by default.")
+ .help_heading(HEADING);
+
+ let current_usage = Arg::new("current_usage")
+ .short('u')
+ .long("current_usage")
+ .action(ArgAction::SetTrue)
+ .help("Sets process CPU% to be based on current CPU%.")
+ .long_help("Sets process CPU% usage to be based on the current system CPU% usage rather than total CPU usage.")
+ .help_heading(HEADING);
+
+ let unnormalized_cpu = Arg::new("unnormalized_cpu")
+ .short('n')
+ .long("unnormalized_cpu")
+ .action(ArgAction::SetTrue)
+ .help("Show process CPU% usage without normalizing over the number of cores.")
+ .long_help(
+ "Shows all process CPU% usage without averaging over the number of CPU cores in the system.",
+ )
+ .help_heading(HEADING);
+
+ let group_processes = Arg::new("group_processes")
+ .short('g')
+ .long("group_processes")
+ .action(ArgAction::SetTrue)
+ .help("Groups processes with the same name by default.")
+ .long_help("Groups processes with the same name by default.")
+ .help_heading(HEADING);
+
+ let process_command = Arg::new("process_command")
+ .long("process_command")
+ .action(ArgAction::SetTrue)
+ .help("Show processes as their commands by default.")
+ .long_help("Show processes as their commands by default in the process widget.")
+ .help_heading(HEADING);
+
+ let regex = Arg::new("regex")
+ .short('R')
+ .long("regex")
+ .action(ArgAction::SetTrue)
+ .help("Enables regex by default.")
+ .long_help("When searching for a process, enables regex by default.")
+ .help_heading(HEADING);
+
+ let disable_advanced_kill = Arg::new("disable_advanced_kill")
+ .long("disable_advanced_kill")
+ .action(ArgAction::SetTrue)
+ .help("Hides advanced process killing.")
+ .long_help("Hides advanced options to stop a process on Unix-like systems. The only option shown is 15 (TERM).")
+ .help_heading(HEADING);
+
+ let whole_word = Arg::new("whole_word")
+ .short('W')
+ .long("whole_word")
+ .action(ArgAction::SetTrue)
+ .help("Enables whole-word matching by default.")
+ .long_help(
+ "When searching for a process, return results that match the entire query by default.",
+ )
+ .help_heading(HEADING);
+
+ let tree = Arg::new("tree")
+ .short('T')
+ .long("tree")
+ .action(ArgAction::SetTrue)
+ .help("Defaults the process widget be in tree mode.")
+ .long_help("Defaults to showing the process widget in tree mode.")
+ .help_heading(HEADING);
+
+ let mut args = [
+ case_sensitive,
+ current_usage,
+ unnormalized_cpu,
+ group_processes,
+ process_command,
+ regex,
+ whole_word,
+ disable_advanced_kill,
+ tree,
+ ];
+ args.sort_unstable();
+
+ self.args(args)
+ }
-And we set our default widget type to 'CPU'. If we set
-'--default_widget_count 1', then it would use the CPU (1) as
-the default widget. If we set '--default_widget_count 3', it would
-use CPU (3) as the default instead.
-",
- );
+ fn cpu_args(self) -> Command {
+ const HEADING: &str = "CPU Options";
- let default_widget_type = Arg::new("default_widget_type")
- .long("default_widget_type")
- .action(ArgAction::Set)
- .value_name("WIDGET TYPE")
- .help("Sets the default widget type, use --help for info.")
- .long_help(DEFAULT_WIDGET_TYPE_STR);
-
- let expanded_on_startup = Arg::new("expanded_on_startup")
- .short('e')
- .long("expanded")
- .action(ArgAction::SetTrue)
- .help("Expand the default widget upon starting the app.")
- .long_help("Expand the default widget upon starting the app. Same as pressing \"e\" inside the app. Use with \"default_widget_type\" and \"default_widget_count\" to select desired expanded widget. This flag has no effect in basic mode (--basic)");
-
- let rate = Arg::new("rate")
- .short('r')
- .long("rate")
- .action(ArgAction::Set)
- .value_name("TIME")
- .help("Sets the data refresh rate.")
- .long_help("Sets the data refresh rate. Takes a number in milliseconds or a human duration (e.g. 5s). The minimum is 250ms, and defaults to 1000ms. Smaller values may take more computer resources.");
-
- let time_delta = Arg::new("time_delta")
- .short('d')
- .long("time_delta")
- .action(ArgAction::Set)
- .value_name("TIME")
- .help("The amount of time changed upon zooming.")
- .long_help("The amount of time changed when zooming in/out. Takes a number in milliseconds or a human duration (e.g. 30s). The minimum is 1s, and defaults to 15s.");
-
- let tree = Arg::new("tree")
- .short('T')
- .long("tree")
- .action(ArgAction::SetTrue)
- .help("Defaults the process widget be in tree mode.")
- .long_help("Defaults to showing the process widget in tree mode.");
-
- let network_use_bytes = Arg::new("network_use_bytes")
- .long("network_use_bytes")
- .action(ArgAction::SetTrue)
- .help("Displays the network widget using bytes.")
- .long_help("Displays the network widget using bytes. Defaults to bits.");
-
- let network_use_log = Arg::new("network_use_log")
- .long("network_use_log")
- .action(ArgAction::SetTrue)
- .help("Displays the network widget with a log scale.")
- .long_help("Displays the network widget with a log scale. Defaults to a non-log scale.");
-
- let network_use_binary_prefix = Arg::new("network_use_binary_prefix")
- .long("network_use_binary_prefix")
- .action(ArgAction::SetTrue)
- .help("Displays the network widget with binary prefixes.")
- .long_help(
- "Displays the network widget with binary prefixes (i.e. kibibits, mebibits) rather than a decimal prefix (i.e. kilobits, megabits). Defaults to decimal prefixes.",
- );
+ let hide_avg_cpu = Arg::new("hide_avg_cpu")
+ .short('a')
+ .long("hide_avg_cpu")
+ .action(ArgAction::SetTrue)
+ .help("Hides the average CPU usage.")
+ .long_help("Hides the average CPU usage from being shown.")
+ .help_heading(HEADING);
- let retention = Arg::new("retention")
- .long("retention")
- .action(ArgAction::Set)
- .value_name("TIME")
- .help("The timespan of data stored.")
- .long_help("How much data is stored at once in terms of time. Takes a number in milliseconds or a human duration (e.g. 20m), with a minimum of 1 minute. Note higher values will take up more memory. Defaults to 10 minutes.");
+ self.arg(hide_avg_cpu)
+ }
- let version = Arg::new("version")
- .short('V')
- .long("version")
- .action(ArgAction::Version)
- .help("Prints version information.");
+ fn mem_args(self) -> Command {
+ const HEADING: &str = "Memory Options";
- const VERSION: &str = match option_env!("NIGHTLY_VERSION") {
- Some(nightly_version) => nightly_version,
- None => crate_version!(),
- };
+ let mem_as_value = Arg::new("mem_as_value")
+ .long("mem_as_value")
+ .action(ArgAction::SetTrue)
+ .help("Defaults to showing process memory usage by value.")
+ .long_help("Defaults to showing process memory usage by value. Otherwise, it defaults to showing it by percentage.")
+ .help_heading(HEADING);
- let temperature_group = ArgGroup::new("TEMPERATURE_TYPE").args([
- kelvin.get_id(),
- fahrenheit.get_id(),
- celsius.get_id(),
- ]);
-
- let mut args = [
- version,
- kelvin,
- fahrenheit,
- celsius,
- autohide_time,
- basic,
- case_sensitive,
- process_command,
- config_location,
- color,
- mem_as_value,
- default_time_value,
- default_widget_count,
- default_widget_type,
- disable_click,
- dot_marker,
- group_processes,
- hide_avg_cpu,
- hide_table_gap,
- hide_time,
- show_table_scroll_position,
- left_legend,
- disable_advanced_kill,
- rate,
- regex,
- time_delta,
- tree,
- network_use_bytes,
- network_use_log,
- network_use_binary_prefix,
- current_usage,
- unnormalized_cpu,
- use_old_network_legend,
- whole_word,
- retention,
- expanded_on_startup,
- #[cfg(feature = "battery")]