other: add explicit short-gpu-names option (#2072)

This PR adds the option to opt in to using the short GPU names setting. Also fix a test and some docs.
This commit is contained in:
Clement Tsang authored and GitHub committed 2026-05-20 06:11:47 +00:00
1 parent 8ef725637a
commit e406ee8347
13 files changed
+131 -19

No files matched your search

+2 -2
View File
@@ -39,7 +39,8 @@ That said, these are more guidelines rather than hard rules, though the project
- [#2046](https://github.com/ClementTsang/bottom/pull/2046): Add a `show_table_scroll_bar` config option to show a scroll bar on table widgets.
- [#2048](https://github.com/ClementTsang/bottom/pull/2048): Add support for a temperature graph to show sensor temperature change over time.
- [#2053](https://github.com/ClementTsang/bottom/pull/2053): Add a configurable default sort column for the process widget (`processes.default_sort` or `--process-default-sort`).
- [#1754](https://github.com/ClementTsang/bottom/issues/1754): Add search support in the help dialog.
- [#2066](https://github.com/ClementTsang/bottom/pull/2066): Add search support in the help dialog.
- [#1791](https://github.com/ClementTsang/bottom/pull/1791), [#2072](https://github.com/ClementTsang/bottom/pull/2072): Add support for using a short name for the GPU in memory usage.
### Changes
@@ -109,7 +110,6 @@ That said, these are more guidelines rather than hard rules, though the project
- [#1891](https://github.com/ClementTsang/bottom/pull/1891): Fix typos in codebase.
- [#1896](https://github.com/ClementTsang/bottom/pull/1896): Rename Linux icon to avoid collision with generic "bottom"
icon.
- [#1913](https://github.com/ClementTsang/bottom/pull/1913): Add `loongarch64-unknown-linux-gnu` binary build target in
CI.
- [#1914](https://github.com/ClementTsang/bottom/pull/1914): Add `aarch64-linux-android` binary build target in CI (with
@@ -66,7 +66,8 @@ see information on these options by running `btm -h`, or run `btm --help` to dis
| ---------------------------- | --------------------------------------------------------- |
| `--memory_legend <POSITION>` | Where to place the legend for the memory chart widget. |
| `--enable_cache_memory` | Enable collecting and displaying cache and buffer memory. |
| `--free_arc` | Subtract freeable ARC from memory. |
| `--free_arc` | Subtract ARC memory that can be freed from memory usage. |
| `--short_gpu_names` | Use short GPU names in the memory widget. |
## Network Options
@@ -59,4 +59,4 @@ each time:
| `disable_keys` | Boolean | Disables keyboard shortcuts, including the ones that stop bottom. |
| `no_write` | Boolean | Disables writing to the config file. |
| `hide_k_threads` | Boolean | Deprecated - use `processes.hide_k_threads`. Hide kernel threads from being shown. |
| `free_arc` | Boolean | Deprecated - use `memory.free_arc`. Subtract freeable ARC from memory usage. |
| `free_arc` | Boolean | Deprecated - use `memory.free_arc`. Subtract ARC memory that can be freed from memory usage. |
@@ -17,11 +17,24 @@ legend_position = "top-left"
On Linux, you can change whether the memory used by [cache/slabs](https://serverfault.com/a/1025189) is collected and
shown. By default, it is `false`.
<!--TODO: Note this affects basic too... should I separate out a "general memory" setting and specific graph ones?-->
```toml
[memory_graph]
cache_memory = true
```
## Short GPU names
If GPU support is enabled, you can use `short_gpu_names` to display simplified GPU names in the memory graph widget
instead of the full GPU names. If enabled, then if there's only one GPU, it'll just list the entry as `GPU`;
if there are multiple GPUs, it'll use entries like `GPU0`, `GPU1`, etc. By default, this is disabled.
```toml
[memory_graph]
short_gpu_names = true
```
## Subtract free-able ARC from memory
If ZFS is detected (note that the `zfs` feature must be enabled if built manually), you can enable `memory_graph.free_arc` to
+17 -1
View File
@@ -141,7 +141,7 @@
#enable_cache_memory = false
# Deprecated - use memory.free_arc.
# Subtract freeable ARC from memory usage
# Subtract ARC memory that can be freed from memory usage.
#free_arc = false
# How much data is stored at once in terms of time.
@@ -319,6 +319,22 @@
#whole_word = false
# Memory widget configuration
#[memory_graph]
# Where to place the legend for the memory widget. One of "none", "top-left", "top", "top-right", "left", "right", "bottom-left", "bottom", "bottom-right".
#legend_position = "top-right"
# Shows cache and buffer memory. Linux only.
#cache_memory = false
# Subtract ARC memory that can be freed from memory usage. Only available if the ZFS feature is enabled when built.
#free_arc = false
# Use short GPU names (e.g. "GPU" or "GPU0", "GPU1") instead of full GPU names. Only available if the GPU feature is enabled when built.
#short_gpu_names = false
# Network widget configuration
#[network_graph]
# By default, there are no network interface filters enabled. An example use case is provided below.
+8 -1
View File
@@ -694,7 +694,7 @@
]
},
"free_arc": {
"description": "Whether to subtract freeable ARC from memory usage.",
"description": "Whether to subtract ARC that can be freed from memory usage.",
"type": [
"boolean",
"null"
@@ -706,6 +706,13 @@
"string",
"null"
]
},
"short_gpu_names": {
"description": "Whether to use short GPU names in the memory widget.",
"type": [
"boolean",
"null"
]
}
}
},
+1
View File
@@ -57,6 +57,7 @@ pub struct AppConfigFields {
pub disable_click: bool,
pub disable_keys: bool,
pub enable_gpu: bool,
pub short_gpu_names: bool,
pub enable_cache_memory: bool,
pub show_table_scroll_position: bool,
pub show_table_scroll_bar: bool,
+11 -5
View File
@@ -136,8 +136,10 @@ impl Painter {
{
let mut colour_index = 0;
let gpu_styles = &self.styles.gpu_colours;
let short_gpu_names = app_state.app_config_fields.short_gpu_names;
let gpu_count = data.gpu_harvest.len();
for (name, harvest) in &data.gpu_harvest {
for (gpu_index, (name, harvest)) in data.gpu_harvest.iter().enumerate() {
if let Some(gpu_data) = data.time_series_data.gpu_mem.get(name) {
let style = {
if gpu_styles.is_empty() {
@@ -150,15 +152,19 @@ impl Painter {
}
};
let display_name = if data.gpu_harvest.len() == 1 {
&"GPU".to_string()
let display_name = if short_gpu_names {
if gpu_count == 1 {
"GPU".to_string()
} else {
format!("GPU{gpu_index}")
}
} else {
name // TODO: REALLY figure out how to line this up better
name.clone()
};
graph_data(
&mut points,
display_name,
&display_name,
Some(harvest),
time,
gpu_data,
+17 -1
View File
@@ -390,7 +390,7 @@ pub(crate) const CONFIG_TEXT: &str = r#"# This is a default config file for bott
#enable_cache_memory = false
# Deprecated - use memory.free_arc.
# Subtract freeable ARC from memory usage
# Subtract ARC memory that can be freed from memory usage.
#free_arc = false
# How much data is stored at once in terms of time.
@@ -568,6 +568,22 @@ pub(crate) const CONFIG_TEXT: &str = r#"# This is a default config file for bott
#whole_word = false
# Memory widget configuration
#[memory_graph]
# Where to place the legend for the memory widget. One of "none", "top-left", "top", "top-right", "left", "right", "bottom-left", "bottom", "bottom-right".
#legend_position = "top-right"
# Shows cache and buffer memory. Linux only.
#cache_memory = false
# Subtract ARC memory that can be freed from memory usage. Only available if the ZFS feature is enabled when built.
#free_arc = false
# Use short GPU names (e.g. "GPU" or "GPU0", "GPU1") instead of full GPU names. Only available if the GPU feature is enabled when built.
#short_gpu_names = false
# Network widget configuration
#[network_graph]
# By default, there are no network interface filters enabled. An example use case is provided below.
+19
View File
@@ -440,6 +440,7 @@ pub(crate) fn init_app(args: BottomArgs, config: Config) -> Result<(App, BottomL
disable_click: is_flag_enabled!(disable_click, args.general, config),
disable_keys: is_flag_enabled!(disable_keys, args.general, config),
enable_gpu: get_enable_gpu(args, config),
short_gpu_names: get_short_gpu_names(args, config),
enable_cache_memory: get_enable_cache_memory(args, config),
show_table_scroll_position: is_flag_enabled!(
show_table_scroll_position,
@@ -1082,6 +1083,24 @@ fn get_enable_gpu(_: &BottomArgs, _: &Config) -> bool {
false
}
#[cfg(feature = "gpu")]
fn get_short_gpu_names(args: &BottomArgs, config: &Config) -> bool {
if args.memory.short_gpu_names {
return true;
}
config
.memory_graph
.as_ref()
.and_then(|m| m.short_gpu_names)
.unwrap_or(false)
}
#[cfg(not(feature = "gpu"))]
fn get_short_gpu_names(_: &BottomArgs, _: &Config) -> bool {
false
}
#[cfg(not(target_os = "windows"))]
fn get_enable_cache_memory(args: &BottomArgs, config: &Config) -> bool {
enabled_option_with_deprecated!(
+9
View File
@@ -540,6 +540,15 @@ pub struct MemoryArgs {
alias = "free-arc"
)]
pub free_arc: bool,
#[cfg(feature = "gpu")]
#[arg(
long,
action = ArgAction::SetTrue,
help = "Use short GPU names (e.g. 'GPU' or 'GPU0', 'GPU1') in the memory widget instead of full GPU names.",
alias = "short-gpu-names"
)]
pub short_gpu_names: bool,
}
/// Network arguments/config options.
+5 -1
View File
@@ -16,7 +16,11 @@ pub struct MemoryGraphConfig {
#[cfg_attr(target_os = "windows", allow(dead_code))]
pub(crate) cache_memory: Option<bool>,
/// Whether to subtract freeable ARC from memory usage.
/// Whether to subtract ARC that can be freed from memory usage.
#[cfg_attr(not(feature = "zfs"), allow(dead_code))]
pub(crate) free_arc: Option<bool>,
/// Whether to use short GPU names in the memory widget.
#[cfg_attr(not(feature = "gpu"), allow(dead_code))]
pub(crate) short_gpu_names: Option<bool>,
}
+26 -6
View File
@@ -1,10 +1,9 @@
//! Tests config files that have sometimes caused issues despite being valid.
use std::{io::Read, thread, time::Duration};
use std::{io::Read, process::Stdio, thread, time::Duration};
#[cfg(feature = "default")]
use std::{io::Write, path::Path};
use assert_cmd::prelude::*;
use predicates::prelude::*;
use crate::util::{btm_command, spawn_btm_in_pty};
@@ -279,10 +278,31 @@ fn test_deprecated_temperature() {
}
/// Test that deprecated warnings are not shown for config options that are not actually set,
/// even when a [flags] section is present.
/// even when a `[flags]` section is present.
#[test]
fn test_no_spurious_deprecated_warnings() {
btm_command(&["-C", "./tests/valid_configs/empty_flags.toml"])
.assert()
.stderr(predicate::str::contains("deprecated").not());
let mut child = btm_command(&["-C", "./tests/valid_configs/empty_flags.toml"])
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.unwrap();
thread::sleep(Duration::from_secs(1));
child.kill().unwrap();
child.wait().unwrap();
let stderr_str = {
let mut stderr = child.stderr.take().unwrap();
let mut buf = String::new();
stderr.read_to_string(&mut buf).unwrap();
buf
};
assert!(
predicate::str::contains("deprecated")
.not()
.eval(&stderr_str),
"Expected no deprecated warnings, but got: {stderr_str}"
);
}