mirror of
https://github.com/uutils/procps.git
synced 2026-05-06 06:06:43 -04:00
top: tui impl ^k (show commandline)
This commit is contained in:
+20
-18
@@ -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
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user