diff options
author | Clement Tsang <34804052+ClementTsang@users.noreply.github.com> | 2024-01-11 00:25:53 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-11 00:25:53 -0500 |
commit | bc2c363a49b185a629e2ce145c7cd94631af9ab2 (patch) | |
tree | 0ae612ee4521c524a9f5f308d05208dd6c25b70e | |
parent | 6b6217655479df639c9ad7f6324939eae4f81cea (diff) |
refactor: clean up arg code more (#1377)
* fix sort function
* Try macros
* Revert "Try macros"
This reverts commit 93c7306f8ae8b906e0a66d1a4d758aad51efe3eb.
* use next_help_heading instead
* test
* Revert "test"
This reverts commit 017a1702b35dd7fd87c449e27a3bdb65bc858f72.
* Reapply "test"
This reverts commit 23c09d3828594d880ecf5e753e1fcdf5fd719e42.
* use foldl instead :)
* a word
* different conditionals
* update docs, change ordering
* more formatting stuff
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | docs/content/configuration/command-line-flags.md | 47 | ||||
-rw-r--r-- | docs/content/configuration/command-line-options.md | 94 | ||||
-rw-r--r-- | docs/content/configuration/config-file/flags.md | 2 | ||||
-rw-r--r-- | docs/content/index.md | 2 | ||||
-rw-r--r-- | docs/content/usage/widgets/network.md | 2 | ||||
-rw-r--r-- | docs/mkdocs.yml | 2 | ||||
-rw-r--r-- | src/options/args.rs | 871 |
8 files changed, 506 insertions, 516 deletions
@@ -78,7 +78,7 @@ As (yet another) process/system visualization and management application, bottom - [Cross-platform support](https://github.com/ClementTsang/bottom#support) for Linux, macOS, and Windows, with more planned in the future. -- [Customizable behaviour](https://clementtsang.github.io/bottom/nightly/configuration/command-line-flags/) that can be controlled with command-line flags or a config file, such as: +- [Customizable behaviour](https://clementtsang.github.io/bottom/nightly/configuration/command-line-options/) that can be controlled with command-line flags or a config file, such as: - Custom and built-in colour themes - Customizing widget behaviour diff --git a/docs/content/configuration/command-line-flags.md b/docs/content/configuration/command-line-flags.md deleted file mode 100644 index e2ab53ae..00000000 --- a/docs/content/configuration/command-line-flags.md +++ /dev/null @@ -1,47 +0,0 @@ -# Command-line Flags - -The following flags can be provided to bottom in the command line to change the behaviour of the program. You can also -see information on these flags by running `btm -h`, or run `btm --help` to display more detailed information on each flag: - -| Flag | Behaviour | -| ----------------------------------- | --------------------------------------------------------------------- | -| --autohide_time | Temporarily shows the time scale in graphs. | -| -b, --basic | Hides graphs and uses a more basic look. | -| --battery | Shows the battery widget. | -| -S, --case_sensitive | Enables case sensitivity by default. | -| -c, --celsius | Sets the temperature type to Celsius. | -| --color <COLOR SCHEME> | Use a color scheme, use --help for info. | -| -C, --config <CONFIG PATH> | Sets the location of the config file. | -| -u, --current_usage | Sets process CPU% to be based on current CPU%. | -| -t, --default_time_value <TIME> | Default time value for graphs. | -| --default_widget_count <INT> | Sets the n'th selected widget type as the default. | -| --default_widget_type <WIDGET TYPE> | Sets the default widget type, use --help for info. | -| --disable_advanced_kill | Hides advanced process killing. | -| --disable_click | Disables mouse clicks. | -| -m, --dot_marker | Uses a dot marker for graphs. | -| --enable_cache_memory | Enable collecting and displaying cache and buffer memory. | -| --enable_gpu | Enable collecting and displaying GPU usage. | -| -e, --expanded | Expand the default widget upon starting the app. | -| -f, --fahrenheit | Sets the temperature type to Fahrenheit. | -| -g, --group_processes | Groups processes with the same name by default. | -| -a, --hide_avg_cpu | Hides the average CPU usage. | -| --hide_table_gap | Hides spacing between table headers and entries. | -| --hide_time | Hides the time scale. | -| -k, --kelvin | Sets the temperature type to Kelvin. | -| -l, --left_legend | Puts the CPU chart legend to the left side. | -| --mem_as_value | Defaults to showing process memory usage by value. | -| --network_use_binary_prefix | Displays the network widget with binary prefixes. | -| --network_use_bytes | Displays the network widget using bytes. | -| --network_use_log | Displays the network widget with a log scale. | -| --process_command | Show processes as their commands by default. | -| -r, --rate <TIME> | Sets the data refresh rate. | -| -R, --regex | Enables regex by default. | -| --retention <TIME> | The timespan of data stored. | -| --show_table_scroll_position | Shows the scroll position tracker in table widgets. | -| -d, --time_delta <TIME> | The amount of time changed upon zooming. | -| -T, --tree | Defaults the process widget be in tree mode. | -| -n, --unnormalized_cpu | Show process CPU% usage without normalizing over the number of cores. | -| --use_old_network_legend | DEPRECATED - uses a separate network legend. | -| -V, --version | Prints version information. | -| -W, --whole_word | Enables whole-word matching by default. | -| -h, --help | Print help (see more with '--help') | diff --git a/docs/content/configuration/command-line-options.md b/docs/content/configuration/command-line-options.md new file mode 100644 index 00000000..2f3a2fd9 --- /dev/null +++ b/docs/content/configuration/command-line-options.md @@ -0,0 +1,94 @@ +# Command-line Options + +The following options can be provided to bottom in the command line to change the behaviour of the program. You can also +see information on these options by running `btm -h`, or run `btm --help` to display more detailed information on each option: + +## General Options + +| Option | Behaviour | +| ----------------------------------- | --------------------------------------------------- | +| --autohide_time | Temporarily shows the time scale in graphs. | +| -b, --basic | Hides graphs and uses a more basic look. | +| -C, --config <CONFIG PATH> | Sets the location of the config file. | +| -t, --default_time_value <TIME> | Default time value for graphs. | +| --default_widget_count <INT> | Sets the n'th selected widget type as the default. | +| --default_widget_type <WIDGET TYPE> | Sets the default widget type, use --help for info. | +| --disable_click | Disables mouse clicks. | +| -m, --dot_marker | Uses a dot marker for graphs. | +| -e, --expanded | Expand the default widget upon starting the app. | +| --hide_table_gap | Hides spacing between table headers and entries. | +| --hide_time | Hides the time scale. | +| -l, --left_legend | Puts the CPU chart legend to the left side. | +| -r, --rate <TIME> | Sets the data refresh rate. | +| --retention <TIME> | The timespan of data stored. | +| --show_table_scroll_position | Shows the scroll position tracker in table widgets. | +| -d, --time_delta <TIME> | The amount of time changed upon zooming. | + +## Process Options + +| Option | Behaviour | +| ----------------------- | --------------------------------------------------------------------- | +| -S, --case_sensitive | Enables case sensitivity by default. | +| -u, --current_usage | Sets process CPU% to be based on current CPU%. | +| --disable_advanced_kill | Hides advanced process killing. | +| -g, --group_processes | Groups processes with the same name by default. | +| --process_command | Show processes as their commands by default. | +| -R, --regex | Enables regex by default. | +| -T, --tree | Defaults the process widget be in tree mode. | +| -n, --unnormalized_cpu | Show process CPU% usage without normalizing over the number of cores. | +| -W, --whole_word | Enables whole-word matching by default. | + +## Temperature Options + +| Option | Behaviour | +| ---------------- | --------------------------------------- | +| -c, --celsius | Use Celsius as the temperature unit. | +| -f, --fahrenheit | Use Fahrenheit as the temperature unit. | +| -k, --kelvin | Use Kelvin as the temperature unit. | + +## CPU Options + +| Option | Behaviour | +| ------------------ | ---------------------------- | +| -a, --hide_avg_cpu | Hides the average CPU usage. | + +## Memory Options + +| Option | Behaviour | +| --------------------- | --------------------------------------------------------- | +| --enable_cache_memory | Enable collecting and displaying cache and buffer memory. | +| --mem_as_value | Defaults to showing process memory usage by value. | + +## Network Options + +| Option | Behaviour | +| --------------------------- | ------------------------------------------------- | +| --network_use_binary_prefix | Displays the network widget with binary prefixes. | +| --network_use_bytes | Displays the network widget using bytes. | +| --network_use_log | Displays the network widget with a log scale. | +| --use_old_network_legend | DEPRECATED - uses a separate network legend. | + +## Battery Options + +| Option | Behaviour | +| --------- | ------------------------- | +| --battery | Shows the battery widget. | + +## GPU Options + +| Option | Behaviour | +| ------------ | ------------------------------------------- | +| --enable_gpu | Enable collecting and displaying GPU usage. | + +## Style Options + +| Option | Behaviour | +| ---------------------- | ---------------------------------------- | +| --color <COLOR SCHEME> | Use a color scheme, use --help for info. | + +## Other Options + +| Option | Behaviour | +| ------------- | ------------------------------------------ | +| -h, --help | Prints help (see more info with '--help'). | +| -V, --version | Prints version information. | diff --git a/docs/content/configuration/config-file/flags.md b/docs/content/configuration/config-file/flags.md index ed9d0aef..c110af6d 100644 --- a/docs/content/configuration/config-file/flags.md +++ b/docs/content/configuration/config-file/flags.md @@ -4,7 +4,7 @@ This section is in progress, and is just copied from the old documentation. -Most of the [command line flags](../command-line-flags.md) have config file equivalents to avoid having to type them out +Most of the [command line flags](../command-line-options.md) have config file equivalents to avoid having to type them out each time: | Field | Type | Functionality | diff --git a/docs/content/index.md b/docs/content/index.md index 2977f67f..39969b9a 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -31,7 +31,7 @@ which contains a list of all the installation methods. You can refer to the [usage](usage/general-usage.md) pages on how to use bottom (e.g. keybinds, some features, a general overview of what each widget does). -To configure bottom, refer to the [configuration](configuration/command-line-flags.md) pages (e.g. how it behaves, how it looks). +To configure bottom, refer to the [configuration](configuration/command-line-options.md) pages (e.g. how it behaves, how it looks). ## Contribution diff --git a/docs/content/usage/widgets/network.md b/docs/content/usage/widgets/network.md index 96369f87..9cf1e9e2 100644 --- a/docs/content/usage/widgets/network.md +++ b/docs/content/usage/widgets/network.md @@ -12,7 +12,7 @@ received and transmitted. The legend displays the current reads and writes per second in bits, as well as the total amount read/written. The y-axis automatically scales based on shown read/write values, and by default, is a linear scale based on base-10 units (e.x. kilobit, gigabit, etc.). -Through [configuration](../../configuration/command-line-flags.md), the read/write per second unit can be changed to bytes, while the y-axis can be changed to a +Through [configuration](../../configuration/command-line-options.md), the read/write per second unit can be changed to bytes, while the y-axis can be changed to a log scale and/or use base-2 units (e.x. kibibit, gibibit, etc.). One can also adjust the displayed time range through either the keyboard or mouse, with a range of 30s to 600s. diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 81a484c1..f76d26cb 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -140,7 +140,7 @@ nav: - "Temperature Widget": usage/widgets/temperature.md - "Battery Widget": usage/widgets/battery.md - "Configuration": - - "Command-line Flags": configuration/command-line-flags.md + - "Command-line Flags": configuration/command-line-options.md - "Config File": - "Default Config": configuration/config-file/default-config.md - "Flags": configuration/config-file/flags.md diff --git a/src/options/args.rs b/src/options/args.rs index 30fe88c9..a2182577 100644 --- a/src/options/args.rs +++ b/src/options/args.rs @@ -3,6 +3,8 @@ //! Note that you probably want to keep this as a single file so the build script doesn't //! trip all over itself. +use std::cmp::Ordering; + use clap::{builder::PossibleValuesParser, *}; const DEFAULT_WIDGET_TYPE_STR: &str = { @@ -80,132 +82,119 @@ pub fn get_matches() -> ArgMatches { build_app().get_matches() } -trait CommandBuilder { - fn general_args(self) -> Self; - - fn style_args(self) -> Self; - - fn temperature_args(self) -> Self; - - fn process_args(self) -> Self; - - fn cpu_args(self) -> Self; - - fn mem_args(self) -> Self; - - fn network_args(self) -> Self; +/// Returns an [`Ordering`] for two [`Arg`] values. +/// +/// Note this assumes that they both have a _long_ name, and will +/// panic if either are missing! +fn sort_args(a: &Arg, b: &Arg) -> Ordering { + let a = a.get_long().unwrap(); + let b = b.get_long().unwrap(); - fn battery_args(self) -> Self; - - fn gpu_args(self) -> Self; + a.cmp(b) +} - fn other(self) -> Self; +/// Create an array of [`Arg`] values. If there is more than one value, then +/// they will be sorted by their long name. Note this sort will panic if +/// any [`Arg`] does not have a long name! +macro_rules! args { + ( $arg:expr $(,)?) => { + [$arg] + }; + ( $( $arg:expr ),+ $(,)? ) => { + { + let mut args = [ $( $arg, )* ]; + args.sort_unstable_by(sort_args); + args + } + }; } -impl CommandBuilder for Command { - fn general_args(self) -> Command { - const HEADING: &str = "General Options"; +fn general_args(cmd: Command) -> Command { + let cmd = cmd.next_help_heading("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 \ + 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 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.", + ); - 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") + 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 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 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 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 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); + + 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( - "\ + .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."); + + // 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. @@ -222,94 +211,85 @@ And we set our default widget type to 'CPU'. If we set 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"; + 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 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."); + + cmd.args(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, + ]) +} - // 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( - "\ +fn style_args(cmd: Command) -> Command { + let cmd = cmd.next_help_heading("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 | @@ -326,285 +306,241 @@ Use a pre-defined color scheme. Currently supported values are: +------------------------------------------------------------+ Defaults to \"default\". ", - ) - .help_heading(HEADING); - - self.arg(color) - } - - 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) - } + cmd.arg(color) +} - fn process_args(self) -> Command { - const HEADING: &str = "Process Options"; +fn temperature_args(cmd: Command) -> Command { + let cmd = cmd.next_help_heading("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."); + + let fahrenheit = Arg::new("fahrenheit") + .short('f') + .long("fahrenheit") + .action(ArgAction::SetTrue) + .help("Use Fahrenheit as the temperature unit."); + + let kelvin = Arg::new("kelvin") + .short('k') + .long("kelvin") + .action(ArgAction::SetTrue) + .help("Use Kelvin as the temperature unit."); + + let temperature_group = ArgGroup::new("TEMPERATURE_TYPE").args([ + celsius.get_id(), + fahrenheit.get_id(), + kelvin.get_id(), + ]); + + cmd.args(args![celsius, fahrenheit, kelvin]) + .group(temperature_group) +} - 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); +fn process_args(cmd: Command) -> Command { + let cmd = cmd.next_help_heading("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."); + + 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."); + + 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 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 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( |