mirror of
https://github.com/ClementTsang/bottom
synced 2024-11-22 12:13:06 +00:00
feature: Add mem_as_value flag (#309)
Adds a new flag, --mem_as_value (and its corresponding config option, mem_as_value = true), which defaults to showing process memory values by their amount rather than percentage.
This commit is contained in:
parent
c0a8c347e1
commit
92636f3bf9
8 changed files with 186 additions and 22 deletions
|
@ -31,6 +31,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
- [#296](https://github.com/ClementTsang/bottom/pull/296): Built-in colour themes.
|
||||
|
||||
- [#309](https://github.com/ClementTsang/bottom/pull/309): Adds a `mem_as_value` flag to default displaying process memory as value rather than percentage.
|
||||
|
||||
### Changes
|
||||
|
||||
- [#213](https://github.com/ClementTsang/bottom/pull/213), [#214](https://github.com/ClementTsang/bottom/pull/214): Updated help descriptions, added auto-complete generation.
|
||||
|
|
|
@ -233,6 +233,7 @@ Run using `btm`.
|
|||
--hide_time Completely hides the time scaling.
|
||||
-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.
|
||||
-r, --rate <MS> Sets a refresh rate in ms.
|
||||
-R, --regex Enables regex by default.
|
||||
-d, --time_delta <MS> The amount in ms changed upon zooming.
|
||||
|
@ -547,6 +548,7 @@ These are the following supported flag config values, which correspond to the fl
|
|||
| `default_widget_count` | Unsigned Int (represents which `default_widget_type`) |
|
||||
| `disable_click` | Boolean |
|
||||
| `color` | String (one of ["default", "default-light", "gruvbox", "gruvbox-light"]) |
|
||||
| `mem_as_value` | Boolean |
|
||||
|
||||
#### Theming
|
||||
|
||||
|
|
37
src/app.rs
37
src/app.rs
|
@ -1,4 +1,5 @@
|
|||
use std::{collections::HashMap, io::Write, path::PathBuf, time::Instant};
|
||||
// use std::io::Write;
|
||||
use std::{collections::HashMap, path::PathBuf, time::Instant};
|
||||
|
||||
use unicode_segmentation::GraphemeCursor;
|
||||
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
|
||||
|
@ -1405,23 +1406,25 @@ impl App {
|
|||
|
||||
/// Call this whenever the config value is updated!
|
||||
fn update_config_file(&mut self) -> anyhow::Result<()> {
|
||||
if self.app_config_fields.no_write {
|
||||
// debug!("No write enabled. Config will not be written.");
|
||||
// Don't write!
|
||||
// FIXME: [CONFIG] This should be made VERY clear to the user... make a thing saying "it will not write due to no_write option"
|
||||
// TODO: Disabled.
|
||||
// if self.app_config_fields.no_write {
|
||||
// // debug!("No write enabled. Config will not be written.");
|
||||
// // Don't write!
|
||||
// // FIXME: [CONFIG] This should be made VERY clear to the user... make a thing saying "it will not write due to no_write option"
|
||||
// Ok(())
|
||||
// } else if let Some(config_path) = &self.config_path {
|
||||
// // Update
|
||||
// // debug!("Updating config file - writing to: {:?}", config_path);
|
||||
// std::fs::File::create(config_path)?
|
||||
// .write_all(self.config.get_config_as_bytes()?.as_ref())?;
|
||||
// Ok(())
|
||||
// } else {
|
||||
// // FIXME: [CONFIG] Put an actual error message?
|
||||
// Err(anyhow::anyhow!(
|
||||
// "Config path was missing, please try restarting bottom..."
|
||||
// ))
|
||||
// }
|
||||
Ok(())
|
||||
} else if let Some(config_path) = &self.config_path {
|
||||
// Update
|
||||
// debug!("Updating config file - writing to: {:?}", config_path);
|
||||
std::fs::File::create(config_path)?
|
||||
.write_all(self.config.get_config_as_bytes()?.as_ref())?;
|
||||
Ok(())
|
||||
} else {
|
||||
// FIXME: [CONFIG] Put an actual error message?
|
||||
Err(anyhow::anyhow!(
|
||||
"Config path was missing, please try restarting bottom..."
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn kill_highlighted_process(&mut self) -> Result<()> {
|
||||
|
|
|
@ -391,6 +391,7 @@ pub struct ProcWidgetState {
|
|||
impl ProcWidgetState {
|
||||
pub fn init(
|
||||
is_case_sensitive: bool, is_match_whole_word: bool, is_use_regex: bool, is_grouped: bool,
|
||||
show_memory_as_values: bool,
|
||||
) -> Self {
|
||||
let mut process_search_state = ProcessSearchState::default();
|
||||
if is_case_sensitive {
|
||||
|
@ -410,9 +411,15 @@ impl ProcWidgetState {
|
|||
let mut columns = ProcColumn::default();
|
||||
columns.set_to_sorted_index(&process_sorting_type);
|
||||
if is_grouped {
|
||||
// Normally defaults to showing by PID, toggle count on instead.
|
||||
columns.toggle(&ProcessSorting::Count);
|
||||
columns.toggle(&ProcessSorting::Pid);
|
||||
}
|
||||
if show_memory_as_values {
|
||||
// Normally defaults to showing by percent, toggle value on instead.
|
||||
columns.toggle(&ProcessSorting::Mem);
|
||||
columns.toggle(&ProcessSorting::MemPercent);
|
||||
}
|
||||
|
||||
ProcWidgetState {
|
||||
process_search_state,
|
||||
|
|
|
@ -227,6 +227,13 @@ Defaults to \"default\".
|
|||
"nord",
|
||||
])
|
||||
.hide_possible_values(true);
|
||||
let mem_as_value = Arg::with_name("mem_as_value")
|
||||
.long("mem_as_value")
|
||||
.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.\n\n",
|
||||
);
|
||||
let default_time_value = Arg::with_name("default_time_value")
|
||||
.short("t")
|
||||
.long("default_time_value")
|
||||
|
@ -345,6 +352,7 @@ The minimum is 1s (1000), and defaults to 15s (15000).\n\n\n",
|
|||
.arg(config_location)
|
||||
.arg(color)
|
||||
.arg(debug)
|
||||
.arg(mem_as_value)
|
||||
.arg(default_time_value)
|
||||
.arg(default_widget_count)
|
||||
.arg(default_widget_type)
|
||||
|
|
130
src/constants.rs
130
src/constants.rs
|
@ -365,9 +365,133 @@ pub const DEFAULT_BATTERY_LAYOUT: &str = r##"
|
|||
// Config and flags
|
||||
pub const DEFAULT_CONFIG_FILE_PATH: &str = "bottom/bottom.toml";
|
||||
|
||||
pub const CONFIG_TOP_HEAD: &str = r##"# This is bottom's config file. Values in this config file will change when changed in the
|
||||
# interface. You can also manually change these values. Be aware that contents of this file will be overwritten if something is
|
||||
# changed in the application; you can disable writing via the --no_write flag or no_write config option.
|
||||
pub const OLD_CONFIG_TEXT: &str = r##"# This is a default config file for bottom. All of the settings are commented
|
||||
# out by default; if you wish to change them uncomment and modify as you see
|
||||
# fit.
|
||||
|
||||
# This group of options represents a command-line flag/option. Flags explicitly
|
||||
# added when running (ie: btm -a) will override this config file if an option
|
||||
# is also set here.
|
||||
[flags]
|
||||
# Whether to hide the average cpu entry.
|
||||
#hide_avg_cpu = false
|
||||
# Whether to use dot markers rather than braille.
|
||||
#dot_marker = false
|
||||
# The update rate of the application.
|
||||
#rate = 1000
|
||||
# Whether to put the CPU legend to the left.
|
||||
#left_legend = false
|
||||
# Whether to set CPU% on a process to be based on the total CPU or just current usage.
|
||||
#current_usage = false
|
||||
# Whether to group processes with the same name together by default.
|
||||
#group_processes = false
|
||||
# Whether to make process searching case sensitive by default.
|
||||
#case_sensitive = false
|
||||
# Whether to make process searching look for matching the entire word by default.
|
||||
#whole_word = false
|
||||
# Whether to make process searching use regex by default.
|
||||
#regex = false
|
||||
# Defaults to Celsius. Temperature is one of:
|
||||
#temperature_type = "k"
|
||||
#temperature_type = "f"
|
||||
#temperature_type = "c"
|
||||
#temperature_type = "kelvin"
|
||||
#temperature_type = "fahrenheit"
|
||||
#temperature_type = "celsius"
|
||||
# The default time interval (in milliseconds).
|
||||
#default_time_value = 60000
|
||||
# The time delta on each zoom in/out action (in milliseconds).
|
||||
#time_delta = 15000
|
||||
# Override layout default widget
|
||||
#default_widget_type = "proc"
|
||||
#default_widget_count = 1
|
||||
# Use basic mode
|
||||
#basic = false
|
||||
# Use the old network legend style
|
||||
#use_old_network_legend = false
|
||||
# Remove space in tables
|
||||
#hide_table_gap = false
|
||||
# Disable mouse clicks
|
||||
#disable_click = false
|
||||
# Built-in themes. Valid values are "default", "default-light", "gruvbox", "gruvbox-light"
|
||||
#color = "default"
|
||||
# Show memory values in the processes widget as values by default
|
||||
# mem_as_value = false
|
||||
|
||||
# These are all the components that support custom theming. Note that colour support
|
||||
# will depend on terminal support.
|
||||
[colors]
|
||||
# Represents the colour of table headers (processes, CPU, disks, temperature).
|
||||
#table_header_color="LightBlue"
|
||||
# Represents the colour of the label each widget has.
|
||||
#widget_title_color="Gray"
|
||||
# Represents the average CPU color.
|
||||
#avg_cpu_color="Red"
|
||||
# Represents the colour the core will use in the CPU legend and graph.
|
||||
#cpu_core_colors=["LightMagenta", "LightYellow", "LightCyan", "LightGreen", "LightBlue", "LightRed", "Cyan", "Green", "Blue", "Red"]
|
||||
# Represents the colour RAM will use in the memory legend and graph.
|
||||
#ram_color="LightMagenta"
|
||||
# Represents the colour SWAP will use in the memory legend and graph.
|
||||
#swap_color="LightYellow"
|
||||
# Represents the colour rx will use in the network legend and graph.
|
||||
#rx_color="LightCyan"
|
||||
# Represents the colour tx will use in the network legend and graph.
|
||||
#tx_color="LightGreen"
|
||||
# Represents the colour of the border of unselected widgets.
|
||||
#border_color="Gray"
|
||||
# Represents the colour of the border of selected widgets.
|
||||
#highlighted_border_color="LightBlue"
|
||||
# Represents the colour of most text.
|
||||
#text_color="Gray"
|
||||
# Represents the colour of text that is selected.
|
||||
#selected_text_color="Black"
|
||||
# Represents the background colour of text that is selected.
|
||||
#selected_bg_color="LightBlue"
|
||||
# Represents the colour of the lines and text of the graph.
|
||||
#graph_color="Gray"
|
||||
# Represents the colours of the battery based on charge
|
||||
#high_battery_color="green"
|
||||
#medium_battery_color="yellow"
|
||||
#low_battery_color="red"
|
||||
|
||||
# Layout - layouts follow a pattern like this:
|
||||
# [[row]] represents a row in the application.
|
||||
# [[row.child]] represents either a widget or a column.
|
||||
# [[row.child.child]] represents a widget.
|
||||
#
|
||||
# All widgets must have the type value set to one of ["cpu", "mem", "proc", "net", "temp", "disk", "empty"].
|
||||
# All layout components have a ratio value - if this is not set, then it defaults to 1.
|
||||
# The default widget layout:
|
||||
#[[row]]
|
||||
# ratio=30
|
||||
# [[row.child]]
|
||||
# type="cpu"
|
||||
#[[row]]
|
||||
# ratio=40
|
||||
# [[row.child]]
|
||||
# ratio=4
|
||||
# type="mem"
|
||||
# [[row.child]]
|
||||
# ratio=3
|
||||
# [[row.child.child]]
|
||||
# type="temp"
|
||||
# [[row.child.child]]
|
||||
# type="disk"
|
||||
#[[row]]
|
||||
# ratio=30
|
||||
# [[row.child]]
|
||||
# type="net"
|
||||
# [[row.child]]
|
||||
# type="proc"
|
||||
# default=true
|
||||
"##;
|
||||
|
||||
pub const CONFIG_TOP_HEAD: &str = r##"# This is bottom's config file.
|
||||
# Values in this config file will change when changed in the interface.
|
||||
# You can also manually change these values.
|
||||
# Be aware that contents of this file will be overwritten if something is
|
||||
# changed in the application; you can disable writing via the
|
||||
# --no_write flag or no_write config option.
|
||||
|
||||
"##;
|
||||
|
||||
|
|
|
@ -225,7 +225,8 @@ pub fn create_or_get_config(config_path: &Option<PathBuf>) -> error::Result<Conf
|
|||
if let Some(parent_path) = path.parent() {
|
||||
fs::create_dir_all(parent_path)?;
|
||||
}
|
||||
fs::File::create(path)?.write_all(CONFIG_TOP_HEAD.as_bytes())?;
|
||||
// fs::File::create(path)?.write_all(CONFIG_TOP_HEAD.as_bytes())?;
|
||||
fs::File::create(path)?.write_all(OLD_CONFIG_TEXT.as_bytes())?;
|
||||
Ok(Config::default())
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -141,6 +141,9 @@ pub struct ConfigFlags {
|
|||
|
||||
#[builder(default, setter(strip_option))]
|
||||
pub search_regex_enabled_widgets: Option<Vec<WidgetIdEnabled>>,
|
||||
|
||||
#[builder(default, setter(strip_option))]
|
||||
pub mem_as_value: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Debug, Deserialize, Serialize)]
|
||||
|
@ -231,6 +234,8 @@ pub fn build_app(
|
|||
let is_custom_layout = config.row.is_some();
|
||||
let mut used_widget_set = HashSet::new();
|
||||
|
||||
let show_memory_as_values = get_mem_as_value(matches, config);
|
||||
|
||||
for row in &widget_layout.rows {
|
||||
for col in &row.children {
|
||||
for col_row in &col.children {
|
||||
|
@ -296,6 +301,7 @@ pub fn build_app(
|
|||
is_match_whole_word,
|
||||
is_use_regex,
|
||||
is_grouped,
|
||||
show_memory_as_values,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -920,3 +926,14 @@ pub fn get_color_scheme(
|
|||
// And lastly, the final case is just "default".
|
||||
Ok(ColourScheme::Default)
|
||||
}
|
||||
|
||||
fn get_mem_as_value(matches: &clap::ArgMatches<'static>, config: &Config) -> bool {
|
||||
if matches.is_present("mem_as_value") {
|
||||
return true;
|
||||
} else if let Some(flags) = &config.flags {
|
||||
if let Some(mem_as_value) = flags.mem_as_value {
|
||||
return mem_as_value;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue