Skip to content

Commit 9264e6a

Browse files
committed
top: tui impl ^k (show commandline)
1 parent 5148eb5 commit 9264e6a

File tree

4 files changed

+79
-30
lines changed

4 files changed

+79
-30
lines changed

src/uu/top/src/picker.rs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,7 @@ fn mem(pid: u32, _stat: Stat) -> Box<dyn Column> {
432432
)
433433
}
434434

435-
fn command(pid: u32, stat: Stat) -> Box<dyn Column> {
436-
let full_command_line = stat.1.full_command_line;
435+
pub(crate) fn get_command(pid: u32, full_command_line: bool) -> String {
437436
let f = |cmd: &[OsString]| -> String {
438437
let binding = cmd
439438
.iter()
@@ -468,23 +467,26 @@ fn command(pid: u32, stat: Stat) -> Box<dyn Column> {
468467

469468
let binding = sysinfo().read().unwrap();
470469
let Some(proc) = binding.process(Pid::from_u32(pid)) else {
471-
return Box::new("?".to_string());
470+
return "?".to_string();
472471
};
473472

474-
Box::new(
475-
proc.exe()
476-
.and_then(|it| {
477-
if full_command_line {
478-
it.iter().next_back()
479-
} else {
480-
it.file_name()
481-
}
482-
})
483-
.map(|it| it.to_str().unwrap().to_string())
484-
.unwrap_or(if full_command_line {
485-
f(proc.cmd())
473+
proc.exe()
474+
.and_then(|it| {
475+
if full_command_line {
476+
it.iter().next_back()
486477
} else {
487-
proc.name().to_str().unwrap().to_string()
488-
}),
489-
)
478+
it.file_name()
479+
}
480+
})
481+
.map(|it| it.to_str().unwrap().to_string())
482+
.unwrap_or(if full_command_line {
483+
f(proc.cmd())
484+
} else {
485+
proc.name().to_str().unwrap().to_string()
486+
})
487+
}
488+
489+
fn command(pid: u32, stat: Stat) -> Box<dyn Column> {
490+
let full_command_line = stat.1.full_command_line;
491+
Box::new(get_command(pid, full_command_line))
490492
}

src/uu/top/src/top.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ impl Settings {
5454

5555
pub(crate) struct ProcList {
5656
pub fields: Vec<String>,
57-
pub collected: Vec<Vec<String>>,
57+
pub collected: Vec<(u32, Vec<String>)>,
5858
}
5959

6060
impl ProcList {
@@ -202,7 +202,7 @@ fn selected_fields() -> Vec<String> {
202202
.collect()
203203
}
204204

205-
fn collect(settings: &Settings, fields: &[String], tui_stat: &TuiStat) -> Vec<Vec<String>> {
205+
fn collect(settings: &Settings, fields: &[String], tui_stat: &TuiStat) -> Vec<(u32, Vec<String>)> {
206206
let pickers = pickers(fields);
207207

208208
let pids = sysinfo()
@@ -219,12 +219,15 @@ fn collect(settings: &Settings, fields: &[String], tui_stat: &TuiStat) -> Vec<Ve
219219
.into_iter()
220220
.filter(|pid| filter(*pid))
221221
.map(|it| {
222-
pickers
223-
.iter()
224-
.map(move |picker| picker(it, (settings, tui_stat)))
225-
.collect::<Vec<_>>()
222+
(
223+
it,
224+
pickers
225+
.iter()
226+
.map(move |picker| picker(it, (settings, tui_stat)))
227+
.collect::<Vec<_>>(),
228+
)
226229
})
227-
.collect::<Vec<Vec<Box<dyn Column>>>>();
230+
.collect::<Vec<(u32, Vec<Box<dyn Column>>)>>();
228231

229232
let sorter = if tui_stat.sort_by_pid {
230233
"PID"
@@ -233,13 +236,18 @@ fn collect(settings: &Settings, fields: &[String], tui_stat: &TuiStat) -> Vec<Ve
233236
};
234237
let sorter_nth = fields.iter().position(|f| f == sorter).unwrap_or(0);
235238
if tui_stat.sort_by_pid {
236-
collected.sort_by(|a, b| a[sorter_nth].cmp_dyn(&*b[sorter_nth])); // reverse
239+
collected.sort_by(|a, b| a.1[sorter_nth].cmp_dyn(&*b.1[sorter_nth])); // reverse
237240
} else {
238-
collected.sort_by(|a, b| b[sorter_nth].cmp_dyn(&*a[sorter_nth]));
241+
collected.sort_by(|a, b| b.1[sorter_nth].cmp_dyn(&*a.1[sorter_nth]));
239242
}
240243
collected
241244
.into_iter()
242-
.map(|it| it.into_iter().map(|c| c.as_string(tui_stat)).collect())
245+
.map(|it| {
246+
(
247+
it.0,
248+
it.1.into_iter().map(|c| c.as_string(tui_stat)).collect(),
249+
)
250+
})
243251
.collect()
244252
}
245253

src/uu/top/src/tui/input.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// file that was distributed with this source code.
55

66
use crate::header::Header;
7+
use crate::picker::get_command;
78
use crate::platform::get_numa_nodes;
89
use crate::tui::stat::{CpuValueMode, TuiStat};
910
use crate::Filter::{EUser, User};
@@ -110,6 +111,32 @@ pub fn handle_input(
110111
data.write().unwrap().1 = ProcList::new(settings, &tui_stat.read().unwrap());
111112
should_update.store(true, Ordering::Relaxed);
112113
}
114+
115+
Event::Key(KeyEvent {
116+
code: KeyCode::Char('k'),
117+
modifiers: KeyModifiers::CONTROL,
118+
..
119+
}) => {
120+
let mut data = data.write().unwrap();
121+
if data.2.is_some() {
122+
data.2 = None;
123+
} else {
124+
let tui_stat = tui_stat.read().unwrap();
125+
let mut nth = tui_stat.list_offset;
126+
if data.1.collected.is_empty() {
127+
return false;
128+
}
129+
if data.1.collected.len() <= nth {
130+
nth = data.1.collected.len() - 1;
131+
}
132+
let pid = data.1.collected[nth].0;
133+
let title =
134+
format!("command line for pid {}, {}", pid, get_command(pid, false));
135+
let content = get_command(pid, true);
136+
data.2 = Some(InfoBar { title, content });
137+
}
138+
should_update.store(true, Ordering::Relaxed);
139+
}
113140
char!('l') => {
114141
let mut stat = tui_stat.write().unwrap();
115142
stat.show_load_avg = !stat.show_load_avg;

src/uu/top/src/tui/mod.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ impl<'a> Tui<'a> {
435435
.proc_list
436436
.collected
437437
.iter()
438-
.map(|item| &item[user_column_nth])
438+
.map(|item| &item.1[user_column_nth])
439439
.collect();
440440
users.iter().map(|u| u.len()).max().unwrap_or_default() + 1
441441
} else {
@@ -479,6 +479,7 @@ impl<'a> Tui<'a> {
479479

480480
let rows = self.proc_list.collected.iter().map(|item| {
481481
let cells = item
482+
.1
482483
.iter()
483484
.enumerate()
484485
.skip(column_coordinates.0)
@@ -531,7 +532,18 @@ impl<'a> Tui<'a> {
531532
Style::default().bg_secondary(self.stat.colorful),
532533
))
533534
.render(layout[0], buf);
534-
Span::raw(&info_bar.content).render(layout[1], buf);
535+
let mut lines = vec![];
536+
let width = layout[1].width as usize;
537+
info_bar.content.lines().for_each(|s| {
538+
let mut start = 0;
539+
let len = s.len();
540+
while start < len {
541+
let end = (start + width).min(len);
542+
lines.push(Line::from(&s[start..end]));
543+
start = end;
544+
}
545+
});
546+
Paragraph::new(lines).render(layout[1], buf);
535547
}
536548
}
537549
}

0 commit comments

Comments
 (0)