top: tui impl ^k (show commandline)

This commit is contained in:
Bluemangoo
2025-10-10 19:31:51 +08:00
parent 5148eb5b40
commit 9264e6ab56
4 changed files with 79 additions and 30 deletions
+20 -18
View File
@@ -432,8 +432,7 @@ fn mem(pid: u32, _stat: Stat) -> Box<dyn Column> {
)
}
fn command(pid: u32, stat: Stat) -> Box<dyn Column> {
let full_command_line = stat.1.full_command_line;
pub(crate) fn get_command(pid: u32, full_command_line: bool) -> String {
let f = |cmd: &[OsString]| -> String {
let binding = cmd
.iter()
@@ -468,23 +467,26 @@ fn command(pid: u32, stat: Stat) -> Box<dyn Column> {
let binding = sysinfo().read().unwrap();
let Some(proc) = binding.process(Pid::from_u32(pid)) else {
return Box::new("?".to_string());
return "?".to_string();
};
Box::new(
proc.exe()
.and_then(|it| {
if full_command_line {
it.iter().next_back()
} else {
it.file_name()
}
})
.map(|it| it.to_str().unwrap().to_string())
.unwrap_or(if full_command_line {
f(proc.cmd())
proc.exe()
.and_then(|it| {
if full_command_line {
it.iter().next_back()
} else {
proc.name().to_str().unwrap().to_string()
}),
)
it.file_name()
}
})
.map(|it| it.to_str().unwrap().to_string())
.unwrap_or(if full_command_line {
f(proc.cmd())
} else {
proc.name().to_str().unwrap().to_string()
})
}
fn command(pid: u32, stat: Stat) -> Box<dyn Column> {
let full_command_line = stat.1.full_command_line;
Box::new(get_command(pid, full_command_line))
}
+18 -10
View File
@@ -54,7 +54,7 @@ impl Settings {
pub(crate) struct ProcList {
pub fields: Vec<String>,
pub collected: Vec<Vec<String>>,
pub collected: Vec<(u32, Vec<String>)>,
}
impl ProcList {
@@ -202,7 +202,7 @@ fn selected_fields() -> Vec<String> {
.collect()
}
fn collect(settings: &Settings, fields: &[String], tui_stat: &TuiStat) -> Vec<Vec<String>> {
fn collect(settings: &Settings, fields: &[String], tui_stat: &TuiStat) -> Vec<(u32, Vec<String>)> {
let pickers = pickers(fields);
let pids = sysinfo()
@@ -219,12 +219,15 @@ fn collect(settings: &Settings, fields: &[String], tui_stat: &TuiStat) -> Vec<Ve
.into_iter()
.filter(|pid| filter(*pid))
.map(|it| {
pickers
.iter()
.map(move |picker| picker(it, (settings, tui_stat)))
.collect::<Vec<_>>()
(
it,
pickers
.iter()
.map(move |picker| picker(it, (settings, tui_stat)))
.collect::<Vec<_>>(),
)
})
.collect::<Vec<Vec<Box<dyn Column>>>>();
.collect::<Vec<(u32, Vec<Box<dyn Column>>)>>();
let sorter = if tui_stat.sort_by_pid {
"PID"
@@ -233,13 +236,18 @@ fn collect(settings: &Settings, fields: &[String], tui_stat: &TuiStat) -> Vec<Ve
};
let sorter_nth = fields.iter().position(|f| f == sorter).unwrap_or(0);
if tui_stat.sort_by_pid {
collected.sort_by(|a, b| a[sorter_nth].cmp_dyn(&*b[sorter_nth])); // reverse
collected.sort_by(|a, b| a.1[sorter_nth].cmp_dyn(&*b.1[sorter_nth])); // reverse
} else {
collected.sort_by(|a, b| b[sorter_nth].cmp_dyn(&*a[sorter_nth]));
collected.sort_by(|a, b| b.1[sorter_nth].cmp_dyn(&*a.1[sorter_nth]));
}
collected
.into_iter()
.map(|it| it.into_iter().map(|c| c.as_string(tui_stat)).collect())
.map(|it| {
(
it.0,
it.1.into_iter().map(|c| c.as_string(tui_stat)).collect(),
)
})
.collect()
}
+27
View File
@@ -4,6 +4,7 @@
// file that was distributed with this source code.
use crate::header::Header;
use crate::picker::get_command;
use crate::platform::get_numa_nodes;
use crate::tui::stat::{CpuValueMode, TuiStat};
use crate::Filter::{EUser, User};
@@ -110,6 +111,32 @@ pub fn handle_input(
data.write().unwrap().1 = ProcList::new(settings, &tui_stat.read().unwrap());
should_update.store(true, Ordering::Relaxed);
}
Event::Key(KeyEvent {
code: KeyCode::Char('k'),
modifiers: KeyModifiers::CONTROL,
..
}) => {
let mut data = data.write().unwrap();
if data.2.is_some() {
data.2 = None;
} else {
let tui_stat = tui_stat.read().unwrap();
let mut nth = tui_stat.list_offset;
if data.1.collected.is_empty() {
return false;
}
if data.1.collected.len() <= nth {
nth = data.1.collected.len() - 1;
}
let pid = data.1.collected[nth].0;
let title =
format!("command line for pid {}, {}", pid, get_command(pid, false));
let content = get_command(pid, true);
data.2 = Some(InfoBar { title, content });
}
should_update.store(true, Ordering::Relaxed);
}
char!('l') => {
let mut stat = tui_stat.write().unwrap();
stat.show_load_avg = !stat.show_load_avg;
+14 -2
View File
@@ -435,7 +435,7 @@ impl<'a> Tui<'a> {
.proc_list
.collected
.iter()
.map(|item| &item[user_column_nth])
.map(|item| &item.1[user_column_nth])
.collect();
users.iter().map(|u| u.len()).max().unwrap_or_default() + 1
} else {
@@ -479,6 +479,7 @@ impl<'a> Tui<'a> {
let rows = self.proc_list.collected.iter().map(|item| {
let cells = item
.1
.iter()
.enumerate()
.skip(column_coordinates.0)
@@ -531,7 +532,18 @@ impl<'a> Tui<'a> {
Style::default().bg_secondary(self.stat.colorful),
))
.render(layout[0], buf);
Span::raw(&info_bar.content).render(layout[1], buf);
let mut lines = vec![];
let width = layout[1].width as usize;
info_bar.content.lines().for_each(|s| {
let mut start = 0;
let len = s.len();
while start < len {
let end = (start + width).min(len);
lines.push(Line::from(&s[start..end]));
start = end;
}
});
Paragraph::new(lines).render(layout[1], buf);
}
}
}