summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2019-10-28 16:19:55 +0200
committerManos Pitsidianakis <el13635@mail.ntua.gr>2019-10-28 17:38:27 +0200
commit1fd52028b072d381e3f6219d67b22aa1e876b284 (patch)
treec465fb47f1bb7af21edafa1be57c5787e4573845
parentb585bda813e5a19c8c935d93cd06df9c8f374fd2 (diff)
Add search function
Initiate search with '/'. Filter function was previously '/', and it was moved to Space.
-rw-r--r--src/ui/components/processes.rs82
-rw-r--r--src/ui/terminal/keys.rs1
2 files changed, 74 insertions, 9 deletions
diff --git a/src/ui/components/processes.rs b/src/ui/components/processes.rs
index c2e494c..d0ada54 100644
--- a/src/ui/components/processes.rs
+++ b/src/ui/components/processes.rs
@@ -183,6 +183,7 @@ enum ProcessListMode {
Normal,
Follow(Pid),
Locate(Pid),
+ Search(String),
Kill(u16),
}
@@ -204,6 +205,13 @@ impl ProcessListMode {
_ => false,
}
}
+
+ fn is_search(&self) -> bool {
+ match self {
+ Search(_) => true,
+ _ => false,
+ }
+ }
}
use ProcessListMode::*;
@@ -399,8 +407,18 @@ impl ProcessList {
self.cursor = std::cmp::min(self.height, self.cursor);
let mut lines = Vec::with_capacity(2048);
let mut iter = self.data.tree.iter().peekable();
+
+ let mut stop_search = false;
while let Some((ind, pid)) = iter.next() {
let p = &self.processes[self.data.processes_index[pid]];
+ if let Search(ref search) = self.mode {
+ if !stop_search && search.len() > 1 && p.cmd_line.0.contains(search) {
+ let i = lines.len(); /* get index from lines to avoid making another counter */
+ pages = i / height;
+ self.cursor = i;
+ stop_search = true;
+ }
+ }
let has_sibling: bool = child_counters
.get(*ind)
.map(|n| {
@@ -765,7 +783,7 @@ impl Component for ProcessList {
return;
}
- let pages = (self.cursor) / height;
+ let mut pages = (self.cursor) / height;
if pages != old_pages {
tick = true;
}
@@ -823,10 +841,14 @@ impl Component for ProcessList {
upper_left = pos_inc(upper_left, (0, 2));
}
- let cmd_header = self
- .filter_term
- .as_ref()
- .map(|filter_term| format!("CMD_LINE (filter: {})", filter_term));
+
+ let cmd_header = if let Search(ref p) = self.mode {
+ Some(format!("CMD_LINE (search: {})", p))
+ } else {
+ self.filter_term
+ .as_ref()
+ .map(|filter_term| format!("CMD_LINE (filter: {})", filter_term))
+ };
/* Write column headers */
let (x, y) = write_string_to_grid(
@@ -891,7 +913,21 @@ impl Component for ProcessList {
});
}
self.height = processes.len();
- self.cursor = std::cmp::min(self.height, self.cursor);
+ self.cursor = if let Search(ref search) = self.mode {
+ let mut ret = self.cursor;
+ if search.len() > 1 {
+ for (i, p) in processes.iter().enumerate() {
+ if p.cmd_line.0.contains(search) {
+ pages = i / height;
+ ret = i;
+ break;
+ }
+ }
+ }
+ ret
+ } else {
+ std::cmp::min(self.height, self.cursor)
+ };
for p in processes.iter().skip(pages * height).take(height) {
let (fg_color, bg_color) = if pages * height + y_offset == self.cursor {
@@ -1276,6 +1312,7 @@ impl Component for ProcessList {
}
UIEvent::Input(k)
if *k == map["toggle help overlay"]
+ && !self.mode.is_search()
&& self.filter_term.is_none() =>
{
self.draw_help = !self.draw_help;
@@ -1320,6 +1357,15 @@ impl Component for ProcessList {
self.dirty = true;
self.force_redraw = true;
}
+ UIEvent::Input(k)
+ if *k == map["search process by name"]
+ && self.mode.is_normal()
+ && self.filter_term.is_none() =>
+ {
+ self.mode = Search(String::new());
+ self.force_redraw = true;
+ self.dirty = true;
+ }
UIEvent::Input(k) if *k == map["kill process"] => {
self.mode = Kill(0);
self.freeze = true;
@@ -1340,13 +1386,15 @@ impl Component for ProcessList {
}
UIEvent::Input(k)
if *k == map["toggle tree view"]
- && !(self.draw_tree && self.filter_term.is_some()) =>
+ && !(self.filter_term.is_some() || self.mode.is_search()) =>
{
self.draw_tree = !self.draw_tree;
self.force_redraw = true;
self.dirty = true;
}
- UIEvent::Input(Key::Char(f)) if self.mode != Normal && f.is_numeric() => {
+ UIEvent::Input(Key::Char(f))
+ if !self.mode.is_normal() && !self.mode.is_search() && f.is_numeric() =>
+ {
if let Kill(ref mut n) = self.mode {
if let Some(add) = (*n).checked_mul(10) {
*n = add
@@ -1362,11 +1410,26 @@ impl Component for ProcessList {
self.dirty = true;
}
}
+ UIEvent::Input(Key::Char(c)) if self.mode.is_search() => {
+ if let Search(ref mut p) = self.mode {
+ if !c.is_ascii_control() {
+ p.push(*c);
+ self.force_redraw = true;
+ self.dirty = true;
+ }
+ }
+ }
UIEvent::Input(Key::Backspace) if self.mode != Normal => {
if let Kill(ref mut n) = self.mode {
*n = *n / 10;
} else if let Locate(ref mut p) = self.mode {
*p = *p / 10;
+ } else if let Search(ref mut p) = self.mode {
+ if p.is_empty() {
+ self.mode = Normal;
+ } else {
+ p.pop();
+ }
}
self.dirty = true;
self.force_redraw = true;
@@ -1413,7 +1476,8 @@ impl Component for ProcessList {
map.insert("freeze updates", Key::Char('f'));
map.insert("toggle tree view", Key::Char('t'));
map.insert("kill process", Key::Char('k'));
- map.insert("filter", Key::Char('/'));
+ map.insert("filter", Key::Char(' '));
+ map.insert("search process by name", Key::Char('/'));
map.insert("cancel", Key::Esc);
map.insert("toggle help overlay", Key::Char('h'));
let mut ret: ShortcutMaps = Default::default();
diff --git a/src/ui/terminal/keys.rs b/src/ui/terminal/keys.rs
index ffa5d4b..2ab7c8b 100644
--- a/src/ui/terminal/keys.rs
+++ b/src/ui/terminal/keys.rs
@@ -77,6 +77,7 @@ impl fmt::Display for Key {
F(n) => write!(f, "F{}", n),
Char('\t') => write!(f, "Tab"),
Char('\n') => write!(f, "Enter"),
+ Char(' ') => write!(f, "Space"),
Char(c) => write!(f, "{}", c),
Alt(c) => write!(f, "M-{}", c),
Ctrl(c) => write!(f, "C-{}", c),