summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Zhao <jeff.no.zhao@gmail.com>2021-07-22 22:29:14 -0400
committerJeff Zhao <jeff.no.zhao@gmail.com>2021-07-22 22:32:14 -0400
commit97ca1fb6d44de66d872422783c38ae198b0edfb9 (patch)
tree695eacc8aaeda28f32fd839169fb8862caf09571
parent4385f6eb523ece963b154f2525f82e8e9f3882f1 (diff)
add automatically_count_files option
- for now, this disables counting number of files in a directory - future plans is to change this to opportunistic file counting - i.e. if we already have the directory loaded, then finding the file count is pretty trivial - it just requires a bit of refactoring
-rw-r--r--config/joshuto.toml3
-rw-r--r--src/config/default/display.rs7
-rw-r--r--src/fs/dirlist.rs11
-rw-r--r--src/fs/entry.rs71
-rw-r--r--src/fs/metadata.rs20
-rw-r--r--src/util/display.rs6
-rw-r--r--src/util/input.rs4
7 files changed, 80 insertions, 42 deletions
diff --git a/config/joshuto.toml b/config/joshuto.toml
index 7f154be..a3b797c 100644
--- a/config/joshuto.toml
+++ b/config/joshuto.toml
@@ -5,8 +5,9 @@ xdg_open = false
use_trash = true
[display]
-# ratios for parent view, current view and preview
+automatically_count_files = false
collapse_preview = true
+# ratios for parent view, current view and preview
column_ratio = [1, 4, 4]
show_borders = true
show_hidden = false
diff --git a/src/config/default/display.rs b/src/config/default/display.rs
index 0e3c006..4663a4c 100644
--- a/src/config/default/display.rs
+++ b/src/config/default/display.rs
@@ -12,6 +12,9 @@ const fn default_true() -> bool {
#[derive(Clone, Debug, Deserialize)]
pub struct DisplayRawOption {
+ #[serde(default)]
+ automatically_count_files: bool,
+
#[serde(default = "default_true")]
collapse_preview: bool,
@@ -58,6 +61,7 @@ impl Flattenable<DisplayOption> for DisplayRawOption {
];
DisplayOption {
+ _automatically_count_files: self.automatically_count_files,
_collapse_preview: self.collapse_preview,
column_ratio,
_show_borders: self.show_borders,
@@ -75,7 +79,8 @@ impl Flattenable<DisplayOption> for DisplayRawOption {
impl std::default::Default for DisplayRawOption {
fn default() -> Self {
Self {
- collapse_preview: default_true(),
+ automatically_count_files: false,
+ collapse_preview: true,
column_ratio: None,
show_borders: true,
show_hidden: false,
diff --git a/src/fs/dirlist.rs b/src/fs/dirlist.rs
index 1414531..80f9089 100644
--- a/src/fs/dirlist.rs
+++ b/src/fs/dirlist.rs
@@ -1,7 +1,7 @@
use std::slice::{Iter, IterMut};
use std::{fs, path};
-use crate::fs::{JoshutoDirEntry, JoshutoMetadata};
+use crate::fs::{FileType, JoshutoDirEntry, JoshutoMetadata};
use crate::util::display::DisplayOption;
#[derive(Clone, Debug)]
@@ -16,7 +16,7 @@ pub struct JoshutoDirList {
impl JoshutoDirList {
pub fn new(path: path::PathBuf, options: &DisplayOption) -> std::io::Result<Self> {
let filter_func = options.filter_func();
- let mut contents = read_dir_list(path.as_path(), filter_func, options.show_icons())?;
+ let mut contents = read_dir_list(path.as_path(), filter_func, &options)?;
let sort_options = options.sort_options_ref();
contents.sort_by(|f1, f2| sort_options.compare(f1, f2));
@@ -75,7 +75,7 @@ impl JoshutoDirList {
pub fn reload_contents(&mut self, options: &DisplayOption) -> std::io::Result<()> {
let filter_func = options.filter_func();
- let mut contents = read_dir_list(self.file_path(), filter_func, options.show_icons())?;
+ let mut contents = read_dir_list(self.file_path(), filter_func, options)?;
let sort_options = options.sort_options_ref();
contents.sort_by(|f1, f2| sort_options.compare(f1, f2));
@@ -174,14 +174,15 @@ impl JoshutoDirList {
fn read_dir_list<F>(
path: &path::Path,
filter_func: F,
- show_icons: bool,
+ options: &DisplayOption,
) -> std::io::Result<Vec<JoshutoDirEntry>>
where
F: Fn(&Result<fs::DirEntry, std::io::Error>) -> bool,
{
let results: Vec<JoshutoDirEntry> = fs::read_dir(path)?
.filter(filter_func)
- .filter_map(|res| JoshutoDirEntry::from(&res.ok()?, show_icons).ok())
+ .filter_map(|res| JoshutoDirEntry::from(&res.ok()?, options).ok())
.collect();
+
Ok(results)
}
diff --git a/src/fs/entry.rs b/src/fs/entry.rs
index 082a6c0..5875a78 100644
--- a/src/fs/entry.rs
+++ b/src/fs/entry.rs
@@ -1,9 +1,10 @@
-use std::{fs, path};
+use std::{fs, io, path};
use crate::fs::{FileType, JoshutoMetadata};
#[cfg(feature = "devicons")]
use crate::util::devicons::*;
+use crate::util::display::DisplayOption;
#[derive(Clone, Debug)]
pub struct JoshutoDirEntry {
@@ -16,46 +17,29 @@ pub struct JoshutoDirEntry {
}
impl JoshutoDirEntry {
- pub fn from(direntry: &fs::DirEntry, show_icons: bool) -> std::io::Result<Self> {
+ pub fn from(direntry: &fs::DirEntry, options: &DisplayOption) -> io::Result<Self> {
let path = direntry.path();
- let metadata = JoshutoMetadata::from(&path)?;
-
+ let mut metadata = JoshutoMetadata::from(&path)?;
let name = direntry
.file_name()
.as_os_str()
.to_string_lossy()
.to_string();
+ if options.automatically_count_files() && metadata.file_type().is_dir() {
+ if let Ok(size) = get_directory_size(path.as_path()) {
+ metadata.update_directory_size(size);
+ }
+ }
+
#[cfg(feature = "devicons")]
- let label = if show_icons {
- let icon = match metadata.file_type() {
- FileType::Directory => DIR_NODE_EXACT_MATCHES
- .get(name.as_str())
- .cloned()
- .unwrap_or(DEFAULT_DIR),
- _ => FILE_NODE_EXACT_MATCHES
- .get(name.as_str())
- .cloned()
- .unwrap_or(match path.extension() {
- Some(s) => FILE_NODE_EXTENSIONS
- .get(match s.to_str() {
- Some(s) => s,
- None => {
- return Err(std::io::Error::new(
- std::io::ErrorKind::Other,
- "Failed converting OsStr to str",
- ))
- }
- })
- .unwrap_or(&DEFAULT_FILE),
- None => DEFAULT_FILE,
- }),
- };
- format!("{} {}", icon, name)
+ let label = if options.show_icons() {
+ create_icon_label(name.as_str(), &metadata)
} else {
name.clone()
};
+
#[cfg(not(feature = "devicons"))]
let label = name.clone();
@@ -69,6 +53,10 @@ impl JoshutoDirEntry {
})
}
+ pub fn update_label(&mut self, label: String) {
+ self.label = label;
+ }
+
pub fn file_name(&self) -> &str {
self.name.as_str()
}
@@ -128,3 +116,28 @@ impl std::cmp::Ord for JoshutoDirEntry {
self.file_path().cmp(other.file_path())
}
}
+
+fn create_icon_label(name: &str, metadata: &JoshutoMetadata) -> String {
+ let label = {
+ let icon =
+ match metadata.file_type() {
+ FileType::Directory => DIR_NODE_EXACT_MATCHES
+ .get(name)
+ .cloned()
+ .unwrap_or(DEFAULT_DIR),
+ _ => FILE_NODE_EXACT_MATCHES.get(name).cloned().unwrap_or(
+ match name.rsplit_once('.') {
+ Some((_, ext)) => FILE_NODE_EXTENSIONS.get(ext).unwrap_or(&DEFAULT_FILE),
+ None => DEFAULT_FILE,
+ },
+ ),
+ };
+ format!("{} {}", icon, name)
+ };
+ label
+}
+
+fn get_directory_size(path: &path::Path) -> io::Result<usize> {
+ let directory_size = fs::read_dir(path).map(|s| s.count());
+ directory_size
+}
diff --git a/src/fs/metadata.rs b/src/fs/metadata.rs
index 0035024..52caac2 100644
--- a/src/fs/metadata.rs
+++ b/src/fs/metadata.rs
@@ -1,11 +1,20 @@
use std::{fs, io, path, time};
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, PartialEq)]
pub enum FileType {
Directory,
File,
}
+impl FileType {
+ pub fn is_dir(&self) -> bool {
+ *self == Self::Directory
+ }
+ pub fn is_file(&self) -> bool {
+ *self == Self::File
+ }
+}
+
#[derive(Clone, Debug)]
pub enum LinkType {
Normal,
@@ -45,10 +54,7 @@ impl JoshutoMetadata {
};
let (_file_type, _directory_size) = match metadata.as_ref() {
- Ok(m) if m.file_type().is_dir() => {
- let _directory_size = fs::read_dir(path).map(|s| s.count()).ok();
- (FileType::Directory, _directory_size)
- }
+ Ok(m) if m.file_type().is_dir() => (FileType::Directory, None),
_ => (FileType::File, None),
};
@@ -98,6 +104,10 @@ impl JoshutoMetadata {
self._directory_size
}
+ pub fn update_directory_size(&mut self, size: usize) {
+ self._directory_size = Some(size);
+ }
+
pub fn modified(&self) -> time::SystemTime {
self._modified
}
diff --git a/src/util/display.rs b/src/util/display.rs
index e271843..913f063 100644
--- a/src/util/display.rs
+++ b/src/util/display.rs
@@ -10,6 +10,7 @@ pub const fn default_column_ratio() -> (usize, usize, usize) {
#[derive(Clone, Debug)]
pub struct DisplayOption {
+ pub _automatically_count_files: bool,
pub _collapse_preview: bool,
pub column_ratio: (usize, usize, usize),
pub _show_borders: bool,
@@ -23,6 +24,10 @@ pub struct DisplayOption {
}
impl DisplayOption {
+ pub fn automatically_count_files(&self) -> bool {
+ self._automatically_count_files
+ }
+
pub fn collapse_preview(&self) -> bool {
self._collapse_preview
}
@@ -86,6 +91,7 @@ impl std::default::Default for DisplayOption {
];
Self {
+ _automatically_count_files: false,
_collapse_preview: true,
column_ratio,
_show_borders: true,
diff --git a/src/util/input.rs b/src/util/input.rs
index 7726bc8..2aa1c76 100644
--- a/src/util/input.rs
+++ b/src/util/input.rs
@@ -66,7 +66,9 @@ pub fn process_finished_worker(context: &mut AppContext, res: std::io::Result<Io
pub fn process_dir_preview(context: &mut AppContext, dirlist: JoshutoDirList) {
let history = context.tab_context_mut().curr_tab_mut().history_mut();
- match history.entry(dirlist.file_path().to_path_buf()) {
+
+ let dir_path = dirlist.file_path().to_path_buf();
+ match history.entry(dir_path) {
Entry::Occupied(mut entry) => {
let old_dirlist = entry.get();
if old_dirlist.need_update() {