other: some cleanup in proc widget (#903)

This commit is contained in:
Clement Tsang 2022-11-20 01:13:24 -05:00 committed by GitHub
parent fd1badaf36
commit 6a0bf10760
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 66 additions and 53 deletions

21
Cargo.lock generated
View file

@ -215,6 +215,7 @@ dependencies = [
"clap_complete",
"clap_mangen",
"concat-string",
"const_format",
"crossterm",
"ctrlc",
"dirs",
@ -360,6 +361,26 @@ dependencies = [
"cache-padded",
]
[[package]]
name = "const_format"
version = "0.2.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7309d9b4d3d2c0641e018d449232f2e28f1b22933c137f157d3dbc14228b8c0e"
dependencies = [
"const_format_proc_macros",
]
[[package]]
name = "const_format_proc_macros"
version = "0.2.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d897f47bf7270cf70d370f8f98c1abb6d2d4cf60a6845d30e05bfb90c6568650"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "core-foundation"
version = "0.7.0"

View file

@ -64,6 +64,7 @@ anyhow = "1.0.57"
backtrace = "0.3.65"
cfg-if = "1.0.0"
clap = { version = "3.1.12", features = ["default", "cargo", "wrap_help"] }
const_format = "0.2.30"
concat-string = "1.0.1"
crossterm = "0.25.0"
ctrlc = { version = "3.1.9", features = ["termination"] }

View file

@ -1,5 +1,6 @@
use std::{borrow::Cow, collections::BTreeMap};
use const_format::formatcp;
use fxhash::{FxHashMap, FxHashSet};
use itertools::Itertools;
@ -385,7 +386,10 @@ impl ProcWidget {
.collect_vec();
stack.sort_unstable_by_key(|p| p.pid);
self.try_sort_skip_pid_asc(&mut stack);
let column = self.table.columns.get(self.table.sort_index()).unwrap();
sort_skip_pid_asc(column.inner(), &mut stack, self.table.order());
stack.reverse();
let mut length_stack = vec![stack.len()];
@ -449,14 +453,13 @@ impl ProcWidget {
data.push(process.prefix(Some(prefix)).disabled(disabled));
if let Some(children_pids) = filtered_tree.get(&pid) {
// TODO: Can probably use static strings for prefixes rather than allocating.
if prefixes.is_empty() {
prefixes.push(String::default());
prefixes.push("");
} else {
prefixes.push(if is_last {
" ".to_string()
" "
} else {
format!("{} ", BRANCH_VERTICAL)
formatcp!("{} ", BRANCH_VERTICAL)
});
}
@ -468,7 +471,9 @@ impl ProcWidget {
})
})
.collect_vec();
self.try_rev_sort(&mut children);
column.sort_by(&mut children, self.table.order().rev());
length_stack.push(children.len());
stack.extend(children);
}
@ -548,33 +553,14 @@ impl ProcWidget {
};
self.id_pid_map = id_pid_map;
self.try_sort_skip_pid_asc(&mut filtered_data);
if let Some(column) = self.table.columns.get(self.table.sort_index()) {
sort_skip_pid_asc(column.inner(), &mut filtered_data, self.table.order());
}
filtered_data
}
#[inline(always)]
fn try_rev_sort(&self, filtered_data: &mut [ProcWidgetData]) {
if let Some(column) = self.table.columns.get(self.table.sort_index()) {
column.sort_by(
filtered_data,
match self.table.order() {
SortOrder::Ascending => SortOrder::Descending,
SortOrder::Descending => SortOrder::Ascending,
},
);
}
}
#[inline(always)]
fn try_sort_skip_pid_asc(&self, filtered_data: &mut [ProcWidgetData]) {
if let Some(column) = self.table.columns.get(self.table.sort_index()) {
let column = column.inner();
let descending = matches!(self.table.order(), SortOrder::Descending);
sort_skip_pid_asc(column, filtered_data, descending);
}
}
#[inline(always)]
fn get_mut_proc_col(&mut self, index: usize) -> Option<&mut ProcColumn> {
self.table.columns.get_mut(index).map(|col| col.inner_mut())
@ -862,7 +848,9 @@ impl ProcWidget {
}
}
fn sort_skip_pid_asc(column: &ProcColumn, data: &mut [ProcWidgetData], descending: bool) {
#[inline]
fn sort_skip_pid_asc(column: &ProcColumn, data: &mut [ProcWidgetData], order: SortOrder) {
let descending = matches!(order, SortOrder::Descending);
match column {
ProcColumn::Pid if !descending => {}
_ => {
@ -876,11 +864,6 @@ mod test {
use super::*;
use crate::app::widgets::MemUsage;
#[test]
fn sorting_trees() {
// FIXME: Add a test for this...
}
#[test]
fn test_proc_sort() {
let a = ProcWidgetData {
@ -903,6 +886,7 @@ mod test {
let b = ProcWidgetData {
pid: 2,
ppid: Some(1),
id: "B".into(),
cpu_usage_percent: 1.1,
mem_usage: MemUsage::Percent(2.2),
@ -911,6 +895,7 @@ mod test {
let c = ProcWidgetData {
pid: 3,
ppid: Some(1),
id: "C".into(),
cpu_usage_percent: 2.2,
mem_usage: MemUsage::Percent(0.0),
@ -919,17 +904,17 @@ mod test {
let d = ProcWidgetData {
pid: 4,
ppid: Some(2),
id: "D".into(),
cpu_usage_percent: 0.0,
mem_usage: MemUsage::Percent(0.0),
..(a.clone())
};
let mut data = vec![d.clone(), b.clone(), c.clone(), a.clone()];
// Assume we had sorted over by pid.
data.sort_by_key(|p| p.pid);
sort_skip_pid_asc(&ProcColumn::CpuPercent, &mut data, true);
sort_skip_pid_asc(&ProcColumn::CpuPercent, &mut data, SortOrder::Descending);
assert_eq!(
vec![&c, &b, &a, &d]
.iter()
@ -940,7 +925,7 @@ mod test {
// Note that the PID ordering for ties is still ascending.
data.sort_by_key(|p| p.pid);
sort_skip_pid_asc(&ProcColumn::CpuPercent, &mut data, false);
sort_skip_pid_asc(&ProcColumn::CpuPercent, &mut data, SortOrder::Ascending);
assert_eq!(
vec![&a, &d, &b, &c]
.iter()
@ -950,7 +935,7 @@ mod test {
);
data.sort_by_key(|p| p.pid);
sort_skip_pid_asc(&ProcColumn::MemoryPercent, &mut data, true);
sort_skip_pid_asc(&ProcColumn::MemoryPercent, &mut data, SortOrder::Descending);
assert_eq!(
vec![&b, &a, &c, &d]
.iter()
@ -961,7 +946,7 @@ mod test {
// Note that the PID ordering for ties is still ascending.
data.sort_by_key(|p| p.pid);
sort_skip_pid_asc(&ProcColumn::MemoryPercent, &mut data, false);
sort_skip_pid_asc(&ProcColumn::MemoryPercent, &mut data, SortOrder::Ascending);
assert_eq!(
vec![&c, &d, &a, &b]
.iter()

View file

@ -213,21 +213,17 @@ impl Painter {
// TODO: [MOUSE] Mouse support for these in search
// TODO: [MOVEMENT] Movement support for these in search
let (case, whole, regex) = if self.is_mac_os {
("Case(F1)", "Whole(F2)", "Regex(F3)")
} else {
("Case(Alt+C)", "Whole(Alt+W)", "Regex(Alt+R)")
};
let option_text = Spans::from(vec![
Span::styled(
format!("Case({})", if self.is_mac_os { "F1" } else { "Alt+C" }),
case_style,
),
Span::styled(case, case_style),
Span::raw(" "),
Span::styled(
format!("Whole({})", if self.is_mac_os { "F2" } else { "Alt+W" }),
whole_word_style,
),
Span::styled(whole, whole_word_style),
Span::raw(" "),
Span::styled(
format!("Regex({})", if self.is_mac_os { "F3" } else { "Alt+R" }),
regex_style,
),
Span::styled(regex, regex_style),
]);
search_text.push(Spans::from(Span::styled(

View file

@ -17,6 +17,16 @@ pub enum SortOrder {
Descending,
}
impl SortOrder {
/// Returns the reverse [`SortOrder`].
pub fn rev(&self) -> SortOrder {
match self {
SortOrder::Ascending => SortOrder::Descending,
SortOrder::Descending => SortOrder::Ascending,
}
}
}
impl Default for SortOrder {
fn default() -> Self {
Self::Ascending