diff --git a/below/model/src/cgroup.rs b/below/model/src/cgroup.rs index 7c4372a2..e789fbd9 100644 --- a/below/model/src/cgroup.rs +++ b/below/model/src/cgroup.rs @@ -108,11 +108,8 @@ impl QueriableContainer for CgroupModel { Some((&s[..idx_end + 1], &s[idx_end + 2..])) } fn get_item(&self, idx: &Self::Idx) -> Option<&SingleCgroupModel> { - let mut model = self; - for part in idx.path.iter() { - model = model.children.get(part.as_str())?; - } - Some(&model.data) + self.get_by_path_iter(idx.path.iter()) + .map(|model| &model.data) } } @@ -274,6 +271,17 @@ impl CgroupModel { }); self } + + fn get_by_path_iter( + &self, + mut path: impl Iterator>, + ) -> Option<&CgroupModel> { + path.try_fold(self, |cur, p| cur.children.get(p.as_ref())) + } + + pub fn get_by_path_str(&self, path: &str) -> Option<&CgroupModel> { + self.get_by_path_iter(path.split('/').filter(|x| !x.is_empty())) + } } impl Nameable for CgroupModel { diff --git a/below/view/src/cgroup_view.rs b/below/view/src/cgroup_view.rs index 286a50f0..1eff7c47 100644 --- a/below/view/src/cgroup_view.rs +++ b/below/view/src/cgroup_view.rs @@ -191,6 +191,17 @@ impl CgroupState { self.uncollapse_cgroup(cgroup.as_str()); self.cgroup_to_focus = Some(cgroup); } + + pub fn collapse_selected_cgroup_children(&mut self) { + if let Some(cur) = self + .get_model() + .get_by_path_str(&self.current_selected_cgroup) + { + self.collapsed_cgroups + .borrow_mut() + .extend(cur.children.iter().map(|c| &c.data.full_path).cloned()); + } + } } // TODO: Make CgroupView a collection of CgroupTab @@ -336,6 +347,11 @@ impl CgroupView { view.state.borrow_mut().set_reverse(true); view.refresh(c) }) + .on_event('=', |c| { + let mut view = Self::get_cgroup_view(c); + view.state.borrow_mut().collapse_selected_cgroup_children(); + view.refresh(c); + }) .with_name(Self::get_view_name()) } @@ -394,14 +410,10 @@ impl ViewBridge for CgroupView { } else { view.get_tag_from_tab_idx(current_tab, selected_column) }; - let field_str = selected_key - .split('/') - // Ignore leading slash - .skip(1) - // Traverse cgroup model tree to find matching model, or None - .try_fold(view.model.borrow(), |model, cgroup_name| { - Ref::filter_map(model, |model| model.children.get(cgroup_name)).ok() - }) + let field_str = view + .model + .borrow() + .get_by_path_str(selected_key) .and_then(|model| model.data.query(&tag)) .map_or("?".to_string(), |field| field.to_string()); format!(" {} : {} ", tag, field_str) diff --git a/below/view/src/help_menu.rs b/below/view/src/help_menu.rs index 856e1a1b..8eb3b882 100644 --- a/below/view/src/help_menu.rs +++ b/below/view/src/help_menu.rs @@ -195,6 +195,7 @@ fn fill_reserved(v: &mut LinearLayout) { " - scroll to top of primary display\n", " - scroll to end of primary display\n", " - collapse/expand cgroup tree, submit command if command palette activated\n", + " '=' - collapse immediate children of selected cgroup\n", " -r - refresh the screen", " 'P' - sort by pid (process view only)\n", " 'N' - sort by name (process view only)\n",