mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-07-31 01:24:31 +02:00
refactor: a bunch of cleanup of dead code and misc. stuff (#1634)
* refactor: lines * shift around some stuff in Cargo.toml * some docs * some more cargo stuff * clean up a bunch of stuff after making things less public * clippy lints * a lot more cleanup * clippy * fix some errors * fix for windows
This commit is contained in:
parent
182c718d0e
commit
ae0d350122
40
Cargo.toml
40
Cargo.toml
@ -1,17 +1,16 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "bottom"
|
name = "bottom"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
authors = ["Clement Tsang <cjhtsang@uwaterloo.ca>"]
|
|
||||||
edition = "2021"
|
|
||||||
repository = "https://github.com/ClementTsang/bottom"
|
repository = "https://github.com/ClementTsang/bottom"
|
||||||
keywords = ["cross-platform", "monitoring", "cli", "top", "tui"]
|
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
categories = ["command-line-utilities", "visualization"]
|
|
||||||
description = "A customizable cross-platform graphical process/system monitor for the terminal. Supports Linux, macOS, and Windows."
|
description = "A customizable cross-platform graphical process/system monitor for the terminal. Supports Linux, macOS, and Windows."
|
||||||
documentation = "https://clementtsang.github.io/bottom/stable"
|
documentation = "https://clementtsang.github.io/bottom/stable"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
default-run = "btm"
|
default-run = "btm"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
authors = ["Clement Tsang <cjhtsang@uwaterloo.ca>"]
|
||||||
|
keywords = ["cross-platform", "monitoring", "cli", "top", "tui"]
|
||||||
|
categories = ["command-line-utilities", "visualization"]
|
||||||
exclude = [
|
exclude = [
|
||||||
".cargo-husky/",
|
".cargo-husky/",
|
||||||
".github/",
|
".github/",
|
||||||
@ -37,6 +36,7 @@ exclude = [
|
|||||||
"rust-toolchain.toml",
|
"rust-toolchain.toml",
|
||||||
"rustfmt.toml",
|
"rustfmt.toml",
|
||||||
]
|
]
|
||||||
|
edition = "2021"
|
||||||
# The oldest version I've tested that should still build - note this is not an official MSRV!
|
# The oldest version I've tested that should still build - note this is not an official MSRV!
|
||||||
rust-version = "1.81"
|
rust-version = "1.81"
|
||||||
|
|
||||||
@ -58,22 +58,6 @@ doctest = false
|
|||||||
doc = false
|
doc = false
|
||||||
required-features = ["generate_schema"]
|
required-features = ["generate_schema"]
|
||||||
|
|
||||||
# Compile dependencies with optimizations enabled, even in debug mode.
|
|
||||||
[profile.dev.package."*"]
|
|
||||||
opt-level = 3
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
debug = 0
|
|
||||||
strip = "symbols"
|
|
||||||
lto = true
|
|
||||||
opt-level = 3
|
|
||||||
codegen-units = 1
|
|
||||||
|
|
||||||
[profile.profiling]
|
|
||||||
inherits = "release"
|
|
||||||
debug = true
|
|
||||||
strip = false
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# Used for general builds.
|
# Used for general builds.
|
||||||
battery = ["starship-battery"]
|
battery = ["starship-battery"]
|
||||||
@ -166,6 +150,22 @@ clap_complete_fig = "4.5.2"
|
|||||||
clap_mangen = "0.2.24"
|
clap_mangen = "0.2.24"
|
||||||
indoc = "2.0.5"
|
indoc = "2.0.5"
|
||||||
|
|
||||||
|
# Compile dependencies with optimizations enabled, even in debug mode.
|
||||||
|
[profile.dev.package."*"]
|
||||||
|
opt-level = 3
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 0
|
||||||
|
strip = "symbols"
|
||||||
|
lto = true
|
||||||
|
opt-level = 3
|
||||||
|
codegen-units = 1
|
||||||
|
|
||||||
|
[profile.profiling]
|
||||||
|
inherits = "release"
|
||||||
|
debug = true
|
||||||
|
strip = false
|
||||||
|
|
||||||
[package.metadata.deb]
|
[package.metadata.deb]
|
||||||
section = "utility"
|
section = "utility"
|
||||||
assets = [
|
assets = [
|
||||||
|
18
build.rs
18
build.rs
@ -1,3 +1,5 @@
|
|||||||
|
//! General build script used by bottom to generate completion files and set binary version.
|
||||||
|
|
||||||
#[expect(dead_code)]
|
#[expect(dead_code)]
|
||||||
#[path = "src/options/args.rs"]
|
#[path = "src/options/args.rs"]
|
||||||
mod args;
|
mod args;
|
||||||
@ -15,15 +17,13 @@ use clap_complete_nushell::Nushell;
|
|||||||
use crate::args::BottomArgs;
|
use crate::args::BottomArgs;
|
||||||
|
|
||||||
fn create_dir(dir: &Path) -> io::Result<()> {
|
fn create_dir(dir: &Path) -> io::Result<()> {
|
||||||
let res = fs::create_dir_all(dir);
|
fs::create_dir_all(dir).inspect_err(|err| {
|
||||||
match &res {
|
eprintln!(
|
||||||
Ok(()) => {}
|
"Couldn't create a directory at {} ({:?}). Aborting.",
|
||||||
Err(err) => {
|
dir.display(),
|
||||||
eprintln!("Failed to create a directory at location {dir:?}, encountered error {err:?}. Aborting...",);
|
err
|
||||||
}
|
)
|
||||||
}
|
})
|
||||||
|
|
||||||
res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_completions<G>(to_generate: G, cmd: &mut Command, out_dir: &Path) -> io::Result<PathBuf>
|
fn generate_completions<G>(to_generate: G, cmd: &mut Command, out_dir: &Path) -> io::Result<PathBuf>
|
||||||
|
34
src/app.rs
34
src/app.rs
@ -27,7 +27,7 @@ use crate::{
|
|||||||
data_conversion::ConvertedData,
|
data_conversion::ConvertedData,
|
||||||
get_network_points,
|
get_network_points,
|
||||||
utils::data_units::DataUnit,
|
utils::data_units::DataUnit,
|
||||||
widgets::{query::ProcessQuery, ProcWidgetColumn, ProcWidgetMode},
|
widgets::{ProcWidgetColumn, ProcWidgetMode},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Default)]
|
#[derive(Debug, Clone, Eq, PartialEq, Default)]
|
||||||
@ -115,8 +115,6 @@ pub struct App {
|
|||||||
pub is_force_redraw: bool,
|
pub is_force_redraw: bool,
|
||||||
pub is_determining_widget_boundary: bool,
|
pub is_determining_widget_boundary: bool,
|
||||||
pub basic_mode_use_percent: bool,
|
pub basic_mode_use_percent: bool,
|
||||||
#[cfg(target_family = "unix")]
|
|
||||||
pub user_table: crate::data_collection::processes::UserTable,
|
|
||||||
pub states: AppWidgetStates,
|
pub states: AppWidgetStates,
|
||||||
pub app_config_fields: AppConfigFields,
|
pub app_config_fields: AppConfigFields,
|
||||||
pub widget_map: HashMap<u64, BottomWidget>,
|
pub widget_map: HashMap<u64, BottomWidget>,
|
||||||
@ -147,8 +145,6 @@ impl App {
|
|||||||
is_force_redraw: false,
|
is_force_redraw: false,
|
||||||
is_determining_widget_boundary: false,
|
is_determining_widget_boundary: false,
|
||||||
basic_mode_use_percent: false,
|
basic_mode_use_percent: false,
|
||||||
#[cfg(target_family = "unix")]
|
|
||||||
user_table: crate::data_collection::processes::UserTable::default(),
|
|
||||||
states,
|
states,
|
||||||
app_config_fields,
|
app_config_fields,
|
||||||
widget_map,
|
widget_map,
|
||||||
@ -670,14 +666,6 @@ impl App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_process_filter(&self, widget_id: u64) -> &Option<ProcessQuery> {
|
|
||||||
if let Some(process_widget_state) = self.states.proc_state.widget_states.get(&widget_id) {
|
|
||||||
&process_widget_state.proc_search.search_state.query
|
|
||||||
} else {
|
|
||||||
&None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
pub fn on_number(&mut self, number_char: char) {
|
pub fn on_number(&mut self, number_char: char) {
|
||||||
if self.delete_dialog_state.is_showing_dd {
|
if self.delete_dialog_state.is_showing_dd {
|
||||||
@ -1990,7 +1978,7 @@ impl App {
|
|||||||
.proc_state
|
.proc_state
|
||||||
.get_mut_widget_state(self.current_widget.widget_id)
|
.get_mut_widget_state(self.current_widget.widget_id)
|
||||||
{
|
{
|
||||||
proc_widget_state.table.to_first();
|
proc_widget_state.table.scroll_to_first();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BottomWidgetType::ProcSort => {
|
BottomWidgetType::ProcSort => {
|
||||||
@ -1999,7 +1987,7 @@ impl App {
|
|||||||
.proc_state
|
.proc_state
|
||||||
.get_mut_widget_state(self.current_widget.widget_id - 2)
|
.get_mut_widget_state(self.current_widget.widget_id - 2)
|
||||||
{
|
{
|
||||||
proc_widget_state.sort_table.to_first();
|
proc_widget_state.sort_table.scroll_to_first();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BottomWidgetType::Temp => {
|
BottomWidgetType::Temp => {
|
||||||
@ -2008,7 +1996,7 @@ impl App {
|
|||||||
.temp_state
|
.temp_state
|
||||||
.get_mut_widget_state(self.current_widget.widget_id)
|
.get_mut_widget_state(self.current_widget.widget_id)
|
||||||
{
|
{
|
||||||
temp_widget_state.table.to_first();
|
temp_widget_state.table.scroll_to_first();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BottomWidgetType::Disk => {
|
BottomWidgetType::Disk => {
|
||||||
@ -2017,7 +2005,7 @@ impl App {
|
|||||||
.disk_state
|
.disk_state
|
||||||
.get_mut_widget_state(self.current_widget.widget_id)
|
.get_mut_widget_state(self.current_widget.widget_id)
|
||||||
{
|
{
|
||||||
disk_widget_state.table.to_first();
|
disk_widget_state.table.scroll_to_first();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BottomWidgetType::CpuLegend => {
|
BottomWidgetType::CpuLegend => {
|
||||||
@ -2026,7 +2014,7 @@ impl App {
|
|||||||
.cpu_state
|
.cpu_state
|
||||||
.get_mut_widget_state(self.current_widget.widget_id - 1)
|
.get_mut_widget_state(self.current_widget.widget_id - 1)
|
||||||
{
|
{
|
||||||
cpu_widget_state.table.to_first();
|
cpu_widget_state.table.scroll_to_first();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2049,7 +2037,7 @@ impl App {
|
|||||||
.proc_state
|
.proc_state
|
||||||
.get_mut_widget_state(self.current_widget.widget_id)
|
.get_mut_widget_state(self.current_widget.widget_id)
|
||||||
{
|
{
|
||||||
proc_widget_state.table.to_last();
|
proc_widget_state.table.scroll_to_last();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BottomWidgetType::ProcSort => {
|
BottomWidgetType::ProcSort => {
|
||||||
@ -2058,7 +2046,7 @@ impl App {
|
|||||||
.proc_state
|
.proc_state
|
||||||
.get_mut_widget_state(self.current_widget.widget_id - 2)
|
.get_mut_widget_state(self.current_widget.widget_id - 2)
|
||||||
{
|
{
|
||||||
proc_widget_state.sort_table.to_last();
|
proc_widget_state.sort_table.scroll_to_last();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BottomWidgetType::Temp => {
|
BottomWidgetType::Temp => {
|
||||||
@ -2067,7 +2055,7 @@ impl App {
|
|||||||
.temp_state
|
.temp_state
|
||||||
.get_mut_widget_state(self.current_widget.widget_id)
|
.get_mut_widget_state(self.current_widget.widget_id)
|
||||||
{
|
{
|
||||||
temp_widget_state.table.to_last();
|
temp_widget_state.table.scroll_to_last();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BottomWidgetType::Disk => {
|
BottomWidgetType::Disk => {
|
||||||
@ -2077,7 +2065,7 @@ impl App {
|
|||||||
.get_mut_widget_state(self.current_widget.widget_id)
|
.get_mut_widget_state(self.current_widget.widget_id)
|
||||||
{
|
{
|
||||||
if !self.converted_data.disk_data.is_empty() {
|
if !self.converted_data.disk_data.is_empty() {
|
||||||
disk_widget_state.table.to_last();
|
disk_widget_state.table.scroll_to_last();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2087,7 +2075,7 @@ impl App {
|
|||||||
.cpu_state
|
.cpu_state
|
||||||
.get_mut_widget_state(self.current_widget.widget_id - 1)
|
.get_mut_widget_state(self.current_widget.widget_id - 1)
|
||||||
{
|
{
|
||||||
cpu_widget_state.table.to_last();
|
cpu_widget_state.table.scroll_to_last();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -28,7 +28,6 @@ use crate::{
|
|||||||
dec_bytes_per_second_string,
|
dec_bytes_per_second_string,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type TimeOffset = f64;
|
|
||||||
pub type Value = f64;
|
pub type Value = f64;
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
|
@ -745,11 +745,6 @@ impl BottomRow {
|
|||||||
self.constraint = IntermediaryConstraint::CanvasHandled { ratio: None };
|
self.constraint = IntermediaryConstraint::CanvasHandled { ratio: None };
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn grow(mut self, minimum: Option<u32>) -> Self {
|
|
||||||
self.constraint = IntermediaryConstraint::Grow { minimum };
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a single column in the layout. We assume that even if the column
|
/// Represents a single column in the layout. We assume that even if the column
|
||||||
@ -785,11 +780,6 @@ impl BottomCol {
|
|||||||
self.constraint = IntermediaryConstraint::CanvasHandled { ratio: None };
|
self.constraint = IntermediaryConstraint::CanvasHandled { ratio: None };
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn grow(mut self, minimum: Option<u32>) -> Self {
|
|
||||||
self.constraint = IntermediaryConstraint::Grow { minimum };
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, Debug)]
|
#[derive(Clone, Default, Debug)]
|
||||||
|
@ -296,14 +296,6 @@ impl NetState {
|
|||||||
widget_states,
|
widget_states,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut NetWidgetState> {
|
|
||||||
self.widget_states.get_mut(&widget_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_widget_state(&self, widget_id: u64) -> Option<&NetWidgetState> {
|
|
||||||
self.widget_states.get(&widget_id)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CpuState {
|
pub struct CpuState {
|
||||||
@ -340,14 +332,6 @@ impl MemState {
|
|||||||
widget_states,
|
widget_states,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut MemWidgetState> {
|
|
||||||
self.widget_states.get_mut(&widget_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_widget_state(&self, widget_id: u64) -> Option<&MemWidgetState> {
|
|
||||||
self.widget_states.get(&widget_id)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TempState {
|
pub struct TempState {
|
||||||
@ -391,7 +375,6 @@ pub struct BasicTableWidgetState {
|
|||||||
// then we can expand outwards with a normal BasicTableState and a hashmap
|
// then we can expand outwards with a normal BasicTableState and a hashmap
|
||||||
pub currently_displayed_widget_type: BottomWidgetType,
|
pub currently_displayed_widget_type: BottomWidgetType,
|
||||||
pub currently_displayed_widget_id: u64,
|
pub currently_displayed_widget_id: u64,
|
||||||
pub widget_id: i64,
|
|
||||||
pub left_tlc: Option<(u16, u16)>,
|
pub left_tlc: Option<(u16, u16)>,
|
||||||
pub left_brc: Option<(u16, u16)>,
|
pub left_brc: Option<(u16, u16)>,
|
||||||
pub right_tlc: Option<(u16, u16)>,
|
pub right_tlc: Option<(u16, u16)>,
|
||||||
@ -410,10 +393,6 @@ impl BatteryState {
|
|||||||
pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut BatteryWidgetState> {
|
pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut BatteryWidgetState> {
|
||||||
self.widget_states.get_mut(&widget_id)
|
self.widget_states.get_mut(&widget_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_widget_state(&self, widget_id: u64) -> Option<&BatteryWidgetState> {
|
|
||||||
self.widget_states.get(&widget_id)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -69,13 +69,13 @@ impl<DataType: DataToCell<H>, H: ColumnHeader, S: SortType, C: DataTableColumn<H
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the scroll position to the first value.
|
/// Sets the scroll position to the first value.
|
||||||
pub fn to_first(&mut self) {
|
pub fn scroll_to_first(&mut self) {
|
||||||
self.state.current_index = 0;
|
self.state.current_index = 0;
|
||||||
self.state.scroll_direction = ScrollDirection::Up;
|
self.state.scroll_direction = ScrollDirection::Up;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the scroll position to the last value.
|
/// Sets the scroll position to the last value.
|
||||||
pub fn to_last(&mut self) {
|
pub fn scroll_to_last(&mut self) {
|
||||||
self.state.current_index = self.data.len().saturating_sub(1);
|
self.state.current_index = self.data.len().saturating_sub(1);
|
||||||
self.state.scroll_direction = ScrollDirection::Down;
|
self.state.scroll_direction = ScrollDirection::Down;
|
||||||
}
|
}
|
||||||
@ -197,11 +197,11 @@ mod test {
|
|||||||
let mut table = DataTable::new(columns, props, styling);
|
let mut table = DataTable::new(columns, props, styling);
|
||||||
table.set_data((0..=4).map(|index| TestType { index }).collect::<Vec<_>>());
|
table.set_data((0..=4).map(|index| TestType { index }).collect::<Vec<_>>());
|
||||||
|
|
||||||
table.to_last();
|
table.scroll_to_last();
|
||||||
assert_eq!(table.current_index(), 4);
|
assert_eq!(table.current_index(), 4);
|
||||||
assert_eq!(table.state.scroll_direction, ScrollDirection::Down);
|
assert_eq!(table.state.scroll_direction, ScrollDirection::Down);
|
||||||
|
|
||||||
table.to_first();
|
table.scroll_to_first();
|
||||||
assert_eq!(table.current_index(), 0);
|
assert_eq!(table.current_index(), 0);
|
||||||
assert_eq!(table.state.scroll_direction, ScrollDirection::Up);
|
assert_eq!(table.state.scroll_direction, ScrollDirection::Up);
|
||||||
|
|
||||||
|
@ -62,8 +62,6 @@ pub trait DataTableColumn<H: ColumnHeader> {
|
|||||||
|
|
||||||
fn is_hidden(&self) -> bool;
|
fn is_hidden(&self) -> bool;
|
||||||
|
|
||||||
fn set_is_hidden(&mut self, is_hidden: bool);
|
|
||||||
|
|
||||||
/// The actually displayed "header".
|
/// The actually displayed "header".
|
||||||
fn header(&self) -> Cow<'static, str>;
|
fn header(&self) -> Cow<'static, str>;
|
||||||
|
|
||||||
@ -114,25 +112,12 @@ impl<H: ColumnHeader> DataTableColumn<H> for Column<H> {
|
|||||||
self.is_hidden
|
self.is_hidden
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn set_is_hidden(&mut self, is_hidden: bool) {
|
|
||||||
self.is_hidden = is_hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn header(&self) -> Cow<'static, str> {
|
fn header(&self) -> Cow<'static, str> {
|
||||||
self.inner.text()
|
self.inner.text()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H: ColumnHeader> Column<H> {
|
impl<H: ColumnHeader> Column<H> {
|
||||||
pub const fn new(inner: H) -> Self {
|
|
||||||
Self {
|
|
||||||
inner,
|
|
||||||
bounds: ColumnWidthBounds::FollowHeader,
|
|
||||||
is_hidden: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn hard(inner: H, width: u16) -> Self {
|
pub const fn hard(inner: H, width: u16) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner,
|
inner,
|
||||||
|
@ -168,11 +168,6 @@ where
|
|||||||
self.is_hidden
|
self.is_hidden
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn set_is_hidden(&mut self, is_hidden: bool) {
|
|
||||||
self.is_hidden = is_hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn header(&self) -> Cow<'static, str> {
|
fn header(&self) -> Cow<'static, str> {
|
||||||
self.inner.header()
|
self.inner.header()
|
||||||
}
|
}
|
||||||
@ -223,12 +218,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the default sort order to [`SortOrder::Ascending`].
|
|
||||||
pub fn default_ascending(mut self) -> Self {
|
|
||||||
self.default_order = SortOrder::Ascending;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the default sort order to [`SortOrder::Descending`].
|
/// Sets the default sort order to [`SortOrder::Descending`].
|
||||||
pub const fn default_descending(mut self) -> Self {
|
pub const fn default_descending(mut self) -> Self {
|
||||||
self.default_order = SortOrder::Descending;
|
self.default_order = SortOrder::Descending;
|
||||||
|
@ -9,6 +9,7 @@ use tui::{
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum LabelLimit {
|
pub enum LabelLimit {
|
||||||
None,
|
None,
|
||||||
|
#[expect(dead_code)]
|
||||||
Auto(u16),
|
Auto(u16),
|
||||||
Bars,
|
Bars,
|
||||||
StartLabel,
|
StartLabel,
|
||||||
|
@ -51,6 +51,7 @@ impl<'a> Axis<'a> {
|
|||||||
/// This is a fluent setter method which must be chained or used as it
|
/// This is a fluent setter method which must be chained or used as it
|
||||||
/// consumes self
|
/// consumes self
|
||||||
#[must_use = "method moves the value of self and returns the modified value"]
|
#[must_use = "method moves the value of self and returns the modified value"]
|
||||||
|
#[cfg_attr(not(test), expect(dead_code))]
|
||||||
pub fn title<T>(mut self, title: T) -> Axis<'a>
|
pub fn title<T>(mut self, title: T) -> Axis<'a>
|
||||||
where
|
where
|
||||||
T: Into<Line<'a>>,
|
T: Into<Line<'a>>,
|
||||||
@ -96,6 +97,7 @@ impl<'a> Axis<'a> {
|
|||||||
///
|
///
|
||||||
/// On the X axis, this parameter only affects the first label.
|
/// On the X axis, this parameter only affects the first label.
|
||||||
#[must_use = "method moves the value of self and returns the modified value"]
|
#[must_use = "method moves the value of self and returns the modified value"]
|
||||||
|
#[expect(dead_code)]
|
||||||
pub fn labels_alignment(mut self, alignment: Alignment) -> Axis<'a> {
|
pub fn labels_alignment(mut self, alignment: Alignment) -> Axis<'a> {
|
||||||
self.labels_alignment = alignment;
|
self.labels_alignment = alignment;
|
||||||
self
|
self
|
||||||
@ -299,6 +301,7 @@ impl<'a> Dataset<'a> {
|
|||||||
/// This is a fluent setter method which must be chained or used as it
|
/// This is a fluent setter method which must be chained or used as it
|
||||||
/// consumes self
|
/// consumes self
|
||||||
#[must_use = "method moves the value of self and returns the modified value"]
|
#[must_use = "method moves the value of self and returns the modified value"]
|
||||||
|
#[expect(dead_code)]
|
||||||
pub fn marker(mut self, marker: symbols::Marker) -> Dataset<'a> {
|
pub fn marker(mut self, marker: symbols::Marker) -> Dataset<'a> {
|
||||||
self.marker = marker;
|
self.marker = marker;
|
||||||
self
|
self
|
||||||
|
@ -9,7 +9,6 @@ pub const STALE_MIN_MILLISECONDS: u64 = 30 * 1000; // Lowest is 30 seconds
|
|||||||
pub const TIME_CHANGE_MILLISECONDS: u64 = 15 * 1000; // How much to increment each time
|
pub const TIME_CHANGE_MILLISECONDS: u64 = 15 * 1000; // How much to increment each time
|
||||||
pub const AUTOHIDE_TIMEOUT_MILLISECONDS: u64 = 5000; // 5 seconds to autohide
|
pub const AUTOHIDE_TIMEOUT_MILLISECONDS: u64 = 5000; // 5 seconds to autohide
|
||||||
|
|
||||||
pub const TICK_RATE_IN_MILLISECONDS: u64 = 200;
|
|
||||||
// How fast the screen refreshes
|
// How fast the screen refreshes
|
||||||
pub const DEFAULT_REFRESH_RATE_IN_MILLISECONDS: u64 = 1000;
|
pub const DEFAULT_REFRESH_RATE_IN_MILLISECONDS: u64 = 1000;
|
||||||
pub const MAX_KEY_TIMEOUT_IN_MILLISECONDS: u64 = 1000;
|
pub const MAX_KEY_TIMEOUT_IN_MILLISECONDS: u64 = 1000;
|
||||||
|
@ -18,6 +18,3 @@ pub struct CpuData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub type CpuHarvest = Vec<CpuData>;
|
pub type CpuHarvest = Vec<CpuData>;
|
||||||
|
|
||||||
pub type PastCpuWork = f64;
|
|
||||||
pub type PastCpuTotal = f64;
|
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use sysinfo::{LoadAvg, System};
|
use sysinfo::System;
|
||||||
|
|
||||||
use super::{CpuData, CpuDataType, CpuHarvest};
|
use super::{CpuData, CpuDataType, CpuHarvest};
|
||||||
use crate::data_collection::{cpu::LoadAvgHarvest, error::CollectionResult};
|
use crate::data_collection::error::CollectionResult;
|
||||||
|
|
||||||
pub fn get_cpu_data_list(sys: &System, show_average_cpu: bool) -> CollectionResult<CpuHarvest> {
|
pub fn get_cpu_data_list(sys: &System, show_average_cpu: bool) -> CollectionResult<CpuHarvest> {
|
||||||
let mut cpu_deque: VecDeque<_> = sys
|
let mut cpu_deque: VecDeque<_> = sys
|
||||||
@ -31,10 +31,11 @@ pub fn get_cpu_data_list(sys: &System, show_average_cpu: bool) -> CollectionResu
|
|||||||
Ok(Vec::from(cpu_deque))
|
Ok(Vec::from(cpu_deque))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_load_avg() -> LoadAvgHarvest {
|
#[cfg(target_family = "unix")]
|
||||||
|
pub(crate) fn get_load_avg() -> crate::data_collection::cpu::LoadAvgHarvest {
|
||||||
// The API for sysinfo apparently wants you to call it like this, rather than
|
// The API for sysinfo apparently wants you to call it like this, rather than
|
||||||
// using a &System.
|
// using a &System.
|
||||||
let LoadAvg { one, five, fifteen } = sysinfo::System::load_average();
|
let sysinfo::LoadAvg { one, five, fifteen } = sysinfo::System::load_average();
|
||||||
|
|
||||||
[one as f32, five as f32, fifteen as f32]
|
[one as f32, five as f32, fifteen as f32]
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,10 @@ pub enum CollectionError {
|
|||||||
General(anyhow::Error),
|
General(anyhow::Error),
|
||||||
|
|
||||||
/// The collection is unsupported.
|
/// The collection is unsupported.
|
||||||
|
#[allow(
|
||||||
|
dead_code,
|
||||||
|
reason = "this is not used if everything is supported for the platform"
|
||||||
|
)]
|
||||||
Unsupported,
|
Unsupported,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +89,7 @@ pub struct ProcessHarvest {
|
|||||||
/// This is the *effective* user ID of the process. This is only used on
|
/// This is the *effective* user ID of the process. This is only used on
|
||||||
/// Unix platforms.
|
/// Unix platforms.
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
|
#[allow(dead_code)]
|
||||||
pub uid: Option<libc::uid_t>,
|
pub uid: Option<libc::uid_t>,
|
||||||
|
|
||||||
/// This is the process' user.
|
/// This is the process' user.
|
||||||
|
@ -484,18 +484,6 @@ pub fn binary_byte_string(value: u64) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a string given a value that is converted to the closest SI-variant.
|
|
||||||
/// If the value is greater than a giga-X, then it will return a decimal place.
|
|
||||||
#[inline]
|
|
||||||
pub fn dec_bytes_per_string(value: u64) -> String {
|
|
||||||
let converted_values = get_decimal_bytes(value);
|
|
||||||
if value >= GIGA_LIMIT {
|
|
||||||
format!("{:.1}{}", converted_values.0, converted_values.1)
|
|
||||||
} else {
|
|
||||||
format!("{:.0}{}", converted_values.0, converted_values.1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a string given a value that is converted to the closest SI-variant,
|
/// Returns a string given a value that is converted to the closest SI-variant,
|
||||||
/// per second. If the value is greater than a giga-X, then it will return a
|
/// per second. If the value is greater than a giga-X, then it will return a
|
||||||
/// decimal place.
|
/// decimal place.
|
||||||
|
26
src/lib.rs
26
src/lib.rs
@ -7,20 +7,20 @@
|
|||||||
//! application. If you are instead looking for documentation regarding the
|
//! application. If you are instead looking for documentation regarding the
|
||||||
//! *usage* of bottom, refer to [here](https://clementtsang.github.io/bottom/stable/).
|
//! *usage* of bottom, refer to [here](https://clementtsang.github.io/bottom/stable/).
|
||||||
|
|
||||||
pub mod app;
|
pub(crate) mod app;
|
||||||
pub mod utils {
|
mod utils {
|
||||||
pub mod cancellation_token;
|
pub(crate) mod cancellation_token;
|
||||||
pub mod data_prefixes;
|
pub(crate) mod data_prefixes;
|
||||||
pub mod data_units;
|
pub(crate) mod data_units;
|
||||||
pub mod general;
|
pub(crate) mod general;
|
||||||
pub mod logging;
|
pub(crate) mod logging;
|
||||||
pub mod strings;
|
pub(crate) mod strings;
|
||||||
}
|
}
|
||||||
pub mod canvas;
|
pub(crate) mod canvas;
|
||||||
pub mod constants;
|
pub(crate) mod constants;
|
||||||
pub mod data_collection;
|
pub(crate) mod data_collection;
|
||||||
pub mod data_conversion;
|
pub(crate) mod data_conversion;
|
||||||
pub mod event;
|
pub(crate) mod event;
|
||||||
pub mod options;
|
pub mod options;
|
||||||
pub mod widgets;
|
pub mod widgets;
|
||||||
|
|
||||||
|
@ -433,7 +433,6 @@ pub(crate) fn init_app(
|
|||||||
Proc | Disk | Temp => BasicTableWidgetState {
|
Proc | Disk | Temp => BasicTableWidgetState {
|
||||||
currently_displayed_widget_type: initial_widget_type,
|
currently_displayed_widget_type: initial_widget_type,
|
||||||
currently_displayed_widget_id: initial_widget_id,
|
currently_displayed_widget_id: initial_widget_id,
|
||||||
widget_id: 100,
|
|
||||||
left_tlc: None,
|
left_tlc: None,
|
||||||
left_brc: None,
|
left_brc: None,
|
||||||
right_tlc: None,
|
right_tlc: None,
|
||||||
@ -442,7 +441,6 @@ pub(crate) fn init_app(
|
|||||||
_ => BasicTableWidgetState {
|
_ => BasicTableWidgetState {
|
||||||
currently_displayed_widget_type: Proc,
|
currently_displayed_widget_type: Proc,
|
||||||
currently_displayed_widget_id: DEFAULT_WIDGET_ID,
|
currently_displayed_widget_id: DEFAULT_WIDGET_ID,
|
||||||
widget_id: 100,
|
|
||||||
left_tlc: None,
|
left_tlc: None,
|
||||||
left_brc: None,
|
left_brc: None,
|
||||||
right_tlc: None,
|
right_tlc: None,
|
||||||
|
@ -14,9 +14,7 @@ impl ColourPalette {
|
|||||||
const HIGHLIGHT_COLOUR: Color = Color::LightBlue;
|
const HIGHLIGHT_COLOUR: Color = Color::LightBlue;
|
||||||
const AVG_COLOUR: Color = Color::Red;
|
const AVG_COLOUR: Color = Color::Red;
|
||||||
const ALL_COLOUR: Color = Color::Green;
|
const ALL_COLOUR: Color = Color::Green;
|
||||||
|
|
||||||
const DEFAULT_SELECTED_TEXT_STYLE: Style = color!(Color::Black).bg(HIGHLIGHT_COLOUR);
|
const DEFAULT_SELECTED_TEXT_STYLE: Style = color!(Color::Black).bg(HIGHLIGHT_COLOUR);
|
||||||
|
|
||||||
const TEXT_COLOUR: Color = Color::Gray;
|
const TEXT_COLOUR: Color = Color::Gray;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
@ -28,16 +28,6 @@ pub const LOG_GIBI_LIMIT: f64 = 30.0;
|
|||||||
pub const LOG_TEBI_LIMIT: f64 = 40.0;
|
pub const LOG_TEBI_LIMIT: f64 = 40.0;
|
||||||
pub const LOG_PEBI_LIMIT: f64 = 50.0;
|
pub const LOG_PEBI_LIMIT: f64 = 50.0;
|
||||||
|
|
||||||
pub const LOG_KILO_LIMIT_U32: u32 = 3;
|
|
||||||
pub const LOG_MEGA_LIMIT_U32: u32 = 6;
|
|
||||||
pub const LOG_GIGA_LIMIT_U32: u32 = 9;
|
|
||||||
pub const LOG_TERA_LIMIT_U32: u32 = 12;
|
|
||||||
|
|
||||||
pub const LOG_KIBI_LIMIT_U32: u32 = 10;
|
|
||||||
pub const LOG_MEBI_LIMIT_U32: u32 = 20;
|
|
||||||
pub const LOG_GIBI_LIMIT_U32: u32 = 30;
|
|
||||||
pub const LOG_TEBI_LIMIT_U32: u32 = 40;
|
|
||||||
|
|
||||||
/// Returns a tuple containing the value and the unit in bytes. In units of
|
/// Returns a tuple containing the value and the unit in bytes. In units of
|
||||||
/// 1024. This only supports up to a tebi. Note the "single" unit will have a
|
/// 1024. This only supports up to a tebi. Note the "single" unit will have a
|
||||||
/// space appended to match the others if `spacing` is true.
|
/// space appended to match the others if `spacing` is true.
|
||||||
|
@ -28,6 +28,7 @@ pub fn partial_ordering_desc<T: PartialOrd>(a: T, b: T) -> Ordering {
|
|||||||
pub trait ClampExt {
|
pub trait ClampExt {
|
||||||
/// Restrict a value by a lower bound. If the current value is _lower_ than
|
/// Restrict a value by a lower bound. If the current value is _lower_ than
|
||||||
/// `lower_bound`, it will be set to `_lower_bound`.
|
/// `lower_bound`, it will be set to `_lower_bound`.
|
||||||
|
#[cfg_attr(not(test), expect(dead_code))]
|
||||||
fn clamp_lower(&self, lower_bound: Self) -> Self;
|
fn clamp_lower(&self, lower_bound: Self) -> Self;
|
||||||
|
|
||||||
/// Restrict a value by an upper bound. If the current value is _greater_
|
/// Restrict a value by an upper bound. If the current value is _greater_
|
||||||
|
@ -13,11 +13,3 @@ pub use mem_graph::*;
|
|||||||
pub use net_graph::*;
|
pub use net_graph::*;
|
||||||
pub use process_table::*;
|
pub use process_table::*;
|
||||||
pub use temperature_table::*;
|
pub use temperature_table::*;
|
||||||
use tui::{layout::Rect, Frame};
|
|
||||||
|
|
||||||
/// A [`Widget`] converts raw data into something that a user can see and
|
|
||||||
/// interact with.
|
|
||||||
pub trait Widget<Data> {
|
|
||||||
/// How to actually draw the widget to the terminal.
|
|
||||||
fn draw(&self, f: &mut Frame<'_>, draw_location: Rect, widget_id: u64);
|
|
||||||
}
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::{borrow::Cow, num::NonZeroU16, time::Instant};
|
use std::{borrow::Cow, num::NonZeroU16, time::Instant};
|
||||||
|
|
||||||
use concat_string::concat_string;
|
use concat_string::concat_string;
|
||||||
use tui::{style::Style, widgets::Row};
|
use tui::widgets::Row;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::AppConfigFields,
|
app::AppConfigFields,
|
||||||
@ -17,38 +17,15 @@ use crate::{
|
|||||||
options::config::{cpu::CpuDefault, style::ColourPalette},
|
options::config::{cpu::CpuDefault, style::ColourPalette},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct CpuWidgetStyling {
|
|
||||||
pub all: Style,
|
|
||||||
pub avg: Style,
|
|
||||||
pub entries: Vec<Style>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CpuWidgetStyling {
|
|
||||||
fn from_colours(palette: &ColourPalette) -> Self {
|
|
||||||
let entries = if palette.cpu_colour_styles.is_empty() {
|
|
||||||
vec![Style::default()]
|
|
||||||
} else {
|
|
||||||
palette.cpu_colour_styles.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
Self {
|
|
||||||
all: palette.all_cpu_colour,
|
|
||||||
avg: palette.avg_cpu_colour,
|
|
||||||
entries,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum CpuWidgetColumn {
|
pub enum CpuWidgetColumn {
|
||||||
CPU,
|
Cpu,
|
||||||
Use,
|
Use,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColumnHeader for CpuWidgetColumn {
|
impl ColumnHeader for CpuWidgetColumn {
|
||||||
fn text(&self) -> Cow<'static, str> {
|
fn text(&self) -> Cow<'static, str> {
|
||||||
match self {
|
match self {
|
||||||
CpuWidgetColumn::CPU => "CPU".into(),
|
CpuWidgetColumn::Cpu => "CPU".into(),
|
||||||
CpuWidgetColumn::Use => "Use".into(),
|
CpuWidgetColumn::Use => "Use".into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,7 +72,7 @@ impl DataToCell<CpuWidgetColumn> for CpuWidgetTableData {
|
|||||||
// *always* hide the CPU column if it is too small.
|
// *always* hide the CPU column if it is too small.
|
||||||
match &self {
|
match &self {
|
||||||
CpuWidgetTableData::All => match column {
|
CpuWidgetTableData::All => match column {
|
||||||
CpuWidgetColumn::CPU => Some("All".into()),
|
CpuWidgetColumn::Cpu => Some("All".into()),
|
||||||
CpuWidgetColumn::Use => None,
|
CpuWidgetColumn::Use => None,
|
||||||
},
|
},
|
||||||
CpuWidgetTableData::Entry {
|
CpuWidgetTableData::Entry {
|
||||||
@ -106,7 +83,7 @@ impl DataToCell<CpuWidgetColumn> for CpuWidgetTableData {
|
|||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
match column {
|
match column {
|
||||||
CpuWidgetColumn::CPU => match data_type {
|
CpuWidgetColumn::Cpu => match data_type {
|
||||||
CpuDataType::Avg => Some("AVG".into()),
|
CpuDataType::Avg => Some("AVG".into()),
|
||||||
CpuDataType::Cpu(index) => {
|
CpuDataType::Cpu(index) => {
|
||||||
let index_str = index.to_string();
|
let index_str = index.to_string();
|
||||||
@ -158,10 +135,8 @@ impl DataToCell<CpuWidgetColumn> for CpuWidgetTableData {
|
|||||||
pub struct CpuWidgetState {
|
pub struct CpuWidgetState {
|
||||||
pub current_display_time: u64,
|
pub current_display_time: u64,
|
||||||
pub is_legend_hidden: bool,
|
pub is_legend_hidden: bool,
|
||||||
pub show_avg: bool,
|
|
||||||
pub autohide_timer: Option<Instant>,
|
pub autohide_timer: Option<Instant>,
|
||||||
pub table: DataTable<CpuWidgetTableData, CpuWidgetColumn>,
|
pub table: DataTable<CpuWidgetTableData, CpuWidgetColumn>,
|
||||||
pub styling: CpuWidgetStyling,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CpuWidgetState {
|
impl CpuWidgetState {
|
||||||
@ -170,7 +145,7 @@ impl CpuWidgetState {
|
|||||||
autohide_timer: Option<Instant>, colours: &ColourPalette,
|
autohide_timer: Option<Instant>, colours: &ColourPalette,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
const COLUMNS: [Column<CpuWidgetColumn>; 2] = [
|
const COLUMNS: [Column<CpuWidgetColumn>; 2] = [
|
||||||
Column::soft(CpuWidgetColumn::CPU, Some(0.5)),
|
Column::soft(CpuWidgetColumn::Cpu, Some(0.5)),
|
||||||
Column::soft(CpuWidgetColumn::Use, Some(0.5)),
|
Column::soft(CpuWidgetColumn::Use, Some(0.5)),
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -196,10 +171,8 @@ impl CpuWidgetState {
|
|||||||
CpuWidgetState {
|
CpuWidgetState {
|
||||||
current_display_time,
|
current_display_time,
|
||||||
is_legend_hidden: false,
|
is_legend_hidden: false,
|
||||||
show_avg: config.show_average_cpu,
|
|
||||||
autohide_timer,
|
autohide_timer,
|
||||||
table,
|
table,
|
||||||
styling: CpuWidgetStyling::from_colours(colours),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -979,13 +979,6 @@ impl ProcWidgetState {
|
|||||||
self.proc_search.search_state.walk_backward();
|
self.proc_search.search_state.walk_backward();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of columns *enabled*. Note this differs from
|
|
||||||
/// *visible* - a column may be enabled but not visible (e.g. off
|
|
||||||
/// screen).
|
|
||||||
pub fn num_enabled_columns(&self) -> usize {
|
|
||||||
self.table.columns.iter().filter(|c| !c.is_hidden).count()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the [`ProcWidgetState`]'s current sort index to whatever was in the
|
/// Sets the [`ProcWidgetState`]'s current sort index to whatever was in the
|
||||||
/// sort table if possible, then closes the sort table.
|
/// sort table if possible, then closes the sort table.
|
||||||
pub(crate) fn use_sort_table_value(&mut self) {
|
pub(crate) fn use_sort_table_value(&mut self) {
|
||||||
|
@ -166,9 +166,10 @@ fn format_time(dur: Duration) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone)]
|
||||||
pub struct ProcWidgetData {
|
pub struct ProcWidgetData {
|
||||||
pub pid: Pid,
|
pub pid: Pid,
|
||||||
|
#[allow(dead_code)]
|
||||||
pub ppid: Option<Pid>,
|
pub ppid: Option<Pid>,
|
||||||
pub id: Id,
|
pub id: Id,
|
||||||
pub cpu_usage_percent: f32,
|
pub cpu_usage_percent: f32,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user