summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorqkzk <qu3nt1n@gmail.com>2023-11-07 19:26:27 +0100
committerqkzk <qu3nt1n@gmail.com>2023-11-07 19:26:27 +0100
commitc449f53b02bdc2392f33a1303e85b50eaa72128f (patch)
tree44e67734b1446542c94b7ce35d304b8cf23a8df5 /src
parent77714cbf215de076a89f4d792b5693b1db48ef76 (diff)
refactor tree and users of tree
Diffstat (limited to 'src')
-rw-r--r--src/completion.rs20
-rw-r--r--src/event_exec.rs2
-rw-r--r--src/status.rs6
-rw-r--r--src/tab.rs2
-rw-r--r--src/tree.rs63
5 files changed, 48 insertions, 45 deletions
diff --git a/src/completion.rs b/src/completion.rs
index 38ed615..e2da514 100644
--- a/src/completion.rs
+++ b/src/completion.rs
@@ -3,7 +3,7 @@ use std::fs::{self, ReadDir};
use anyhow::Result;
use strum::IntoEnumIterator;
-use crate::fileinfo::PathContent;
+use crate::{fileinfo::PathContent, tree::Node};
/// Different kind of completions
#[derive(Clone, Default, Copy)]
@@ -215,18 +215,18 @@ impl Completion {
pub fn search_from_tree(
&mut self,
input_string: &str,
- content: &[&std::ffi::OsStr],
+ content: std::iter::FilterMap<
+ std::iter::FilterMap<
+ std::collections::hash_map::Keys<'_, std::path::PathBuf, Node>,
+ fn(&std::path::PathBuf) -> Option<&std::ffi::OsStr>,
+ >,
+ fn(&std::ffi::OsStr) -> Option<&str>,
+ >,
) -> Result<()> {
self.update(
content
- .iter()
- .filter(|&p| p.to_string_lossy().contains(input_string))
- .map(|p| {
- p.to_string_lossy()
- .into_owned()
- .replace("▸ ", "")
- .replace("▾ ", "")
- })
+ .filter(|&p| p.contains(input_string))
+ .map(|p| p.replace("▸ ", "").replace("▾ ", ""))
.collect(),
);
diff --git a/src/event_exec.rs b/src/event_exec.rs
index dd467dd..c1fcbe4 100644
--- a/src/event_exec.rs
+++ b/src/event_exec.rs
@@ -1450,7 +1450,7 @@ impl LeaveMode {
/// Execute the selected node if it's a file else enter the directory.
pub fn tree(status: &mut Status) -> Result<()> {
- let path = status.selected_fileinfo()?.path;
+ let path = status.selected_non_mut().selected()?.path;
let is_dir = path.is_dir();
if is_dir {
status.selected().set_pathcontent(&path)?;
diff --git a/src/status.rs b/src/status.rs
index f0b9f01..68e940d 100644
--- a/src/status.rs
+++ b/src/status.rs
@@ -20,7 +20,7 @@ use crate::config::Settings;
use crate::constant_strings_paths::{NVIM, SS, TUIS_PATH};
use crate::copy_move::{copy_move, CopyMove};
use crate::cryptsetup::{BlockDeviceAction, CryptoDeviceOpener};
-use crate::fileinfo::{FileInfo, FileKind};
+use crate::fileinfo::FileKind;
use crate::flagged::Flagged;
use crate::iso::IsoDevice;
use crate::log_line;
@@ -258,10 +258,6 @@ impl Status {
&self.tabs[self.index]
}
- pub fn selected_fileinfo(&self) -> Result<FileInfo> {
- self.selected_non_mut().selected()
- }
-
/// Reset the view of every tab.
pub fn reset_tabs_view(&mut self) -> Result<()> {
for tab in self.tabs.iter_mut() {
diff --git a/src/tab.rs b/src/tab.rs
index ea2eab3..e201091 100644
--- a/src/tab.rs
+++ b/src/tab.rs
@@ -131,7 +131,7 @@ impl Tab {
if matches!(self.previous_mode, Mode::Tree) =>
{
self.completion
- .search_from_tree(&self.input.string(), &self.tree.filenames())
+ .search_from_tree(&self.input.string(), self.tree.filenames())
}
Mode::InputCompleted(InputCompleted::Command) => {
self.completion.command(&self.input.string())
diff --git a/src/tree.rs b/src/tree.rs
index a3d5375..a44eea1 100644
--- a/src/tree.rs
+++ b/src/tree.rs
@@ -1,5 +1,8 @@
use std::{
+ collections::hash_map,
collections::HashMap,
+ ffi::OsStr,
+ iter::FilterMap,
path::{Path, PathBuf},
};
@@ -45,7 +48,7 @@ pub struct Node {
}
impl Node {
- pub fn new(path: &Path, children: Option<Vec<PathBuf>>) -> Self {
+ fn new(path: &Path, children: Option<Vec<PathBuf>>) -> Self {
Self {
path: path.to_owned(),
children,
@@ -54,23 +57,23 @@ impl Node {
}
}
- pub fn fold(&mut self) {
+ fn fold(&mut self) {
self.folded = true
}
- pub fn unfold(&mut self) {
+ fn unfold(&mut self) {
self.folded = false
}
- pub fn toggle_fold(&mut self) {
+ fn toggle_fold(&mut self) {
self.folded = !self.folded
}
- pub fn select(&mut self) {
+ fn select(&mut self) {
self.selected = true
}
- pub fn unselect(&mut self) {
+ fn unselect(&mut self) {
self.selected = false
}
@@ -82,12 +85,13 @@ impl Node {
FileInfo::new(&self.path, users)
}
- pub fn color_effect(&self, users: &Users) -> Result<ColorEffect> {
- Ok(ColorEffect::new(&self.fileinfo(users)?))
+ fn set_children(&mut self, children: Option<Vec<PathBuf>>) {
+ self.children = children
}
- pub fn set_children(&mut self, children: Option<Vec<PathBuf>>) {
- self.children = children
+ #[inline]
+ fn have_children(self: &Node) -> bool {
+ !self.folded && self.children.is_some()
}
}
@@ -108,7 +112,7 @@ pub enum To<'a> {
impl Go for Tree {
fn go(&mut self, direction: To) {
match direction {
- To::Next => self.select_next().unwrap_or_else(|_| ()),
+ To::Next => self.select_next(),
To::Prev => self.select_prev(),
To::Root => self.select_root(),
To::Last => self.select_last(),
@@ -157,7 +161,9 @@ impl Tree {
{
sort_kind.sort(&mut files);
let children = Self::make_children_and_stack_them(&mut stack, &files);
- node.set_children(Some(children));
+ if !children.is_empty() {
+ node.set_children(Some(children));
+ }
};
}
last_path = node.path.to_owned();
@@ -240,17 +246,16 @@ impl Tree {
}
/// Select next sibling or the next sibling of the parent
- pub fn select_next(&mut self) -> Result<()> {
+ pub fn select_next(&mut self) {
if self.is_on_last() {
self.select_root();
- return Ok(());
+ return;
}
if let Some(next_path) = self.find_next_path() {
let Some(next_node) = self.nodes.get_mut(&next_path) else {
- return Ok(());
+ return;
};
- log::info!("selecting {next_node:?}");
next_node.select();
let Some(selected_node) = self.nodes.get_mut(&self.selected) else {
unreachable!("current_node should be in nodes");
@@ -259,7 +264,6 @@ impl Tree {
self.selected = next_path;
self.increment_required_height()
}
- Ok(())
}
// FIX: Still a problem when reaching max depth of tree,
@@ -497,7 +501,7 @@ impl Tree {
path,
));
- if Self::have_interesting_children(path, node) {
+ if node.have_children() {
Self::stack_children(&mut stack, prefix, node);
}
@@ -508,11 +512,19 @@ impl Tree {
(selected_index, content)
}
- pub fn filenames(&self) -> Vec<&std::ffi::OsStr> {
- self.nodes
- .keys()
- .filter_map(|path| path.file_name())
- .collect()
+ /// An (ugly) iterator over filenames.
+ /// It allows us to iter explicitely over filenames
+ /// while avoiding another allocation by collecting into a `Vec`
+ #[inline]
+ pub fn filenames(
+ &self,
+ ) -> FilterMap<
+ FilterMap<hash_map::Keys<'_, PathBuf, Node>, fn(&PathBuf) -> Option<&OsStr>>,
+ fn(&OsStr) -> Option<&str>,
+ > {
+ let to_filename: fn(&PathBuf) -> Option<&OsStr> = |path| path.file_name();
+ let to_str: fn(&OsStr) -> Option<&str> = |filename| filename.to_str();
+ self.nodes.keys().filter_map(to_filename).filter_map(to_str)
}
#[inline]
@@ -537,11 +549,6 @@ impl Tree {
stack.push((other_prefix.clone(), leaf));
}
}
-
- #[inline]
- fn have_interesting_children(current_path: &Path, current_node: &Node) -> bool {
- current_path.is_dir() && !current_path.is_symlink() && !current_node.folded
- }
}
#[inline]