summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2020-01-22 21:45:48 +0100
committerrabite <rabite@posteo.de>2020-01-23 04:12:57 +0100
commitc9f33126404d2c23c8667bff9c20183151629ab0 (patch)
treecf63dc72d88101e5b16afe9296907129d26b8e7f
parent325f5a5ab3f44457263d7d5c04e488faea0d369e (diff)
save number of visible files instead of recalculating it every time
-rw-r--r--src/files.rs85
-rw-r--r--src/fscache.rs15
-rw-r--r--src/listview.rs2
3 files changed, 66 insertions, 36 deletions
diff --git a/src/files.rs b/src/files.rs
index ccdaabf..25d21ad 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -103,6 +103,7 @@ pub fn tags_loaded() -> HResult<()> {
pub struct RefreshPackage {
pub new_files: Option<Vec<File>>,
pub new_buffer: Option<Vec<String>>,
+ pub new_len: usize,
}
@@ -187,6 +188,9 @@ impl RefreshPackage {
// Finally add all new files
files.files.extend(new_files);
+ // Files added, removed, renamed to hidden, etc...
+ files.recalculate_len();
+ let new_len = files.len();
// Need to unpack this to prevent issue with recursive Files type
// Also, if no files remain add placeholder
let files = if files.len() > 0 {
@@ -222,6 +226,7 @@ impl RefreshPackage {
RefreshPackage {
new_files: Some(files),
new_buffer: Some(new_buffer),
+ new_len: new_len
}
}
}
@@ -232,6 +237,7 @@ impl RefreshPackage {
pub struct Files {
pub directory: File,
pub files: Vec<File>,
+ pub len: usize,
#[derivative(Debug="ignore")]
#[derivative(PartialEq="ignore")]
#[derivative(Hash="ignore")]
@@ -273,11 +279,33 @@ impl Dirtyable for Files {
}
}
+use std::default::Default;
+
+impl Default for Files {
+ fn default() -> Files {
+ Files {
+ directory: File::new_placeholder(Path::new("")).unwrap(),
+ files: vec![],
+ len: 0,
+ pending_events: Arc::new(RwLock::new(vec![])),
+ refresh: None,
+ meta_upto: None,
+ sort: SortBy::Name,
+ dirs_first: true,
+ reverse: false,
+ show_hidden: true,
+ filter: None,
+ filter_selected: false,
+ dirty: DirtyBit::new(),
+ dirty_meta: AsyncDirtyBit::new(),
+ }
+ }
+}
+
impl Files {
pub fn new_from_path(path: &Path) -> Result<Files, Error> {
let direntries: Result<Vec<_>, _> = std::fs::read_dir(&path)?.collect();
- let dirty = DirtyBit::new();
let dirty_meta = AsyncDirtyBit::new();
let files: Vec<_> = direntries?
@@ -292,29 +320,13 @@ impl Files {
})
.collect();
- let mut files = Files {
- directory: File::new_from_path(&path, None)?,
- files: files,
- pending_events: Arc::new(RwLock::new(vec![])),
- refresh: None,
- meta_upto: None,
- sort: SortBy::Name,
- dirs_first: true,
- reverse: false,
- show_hidden: true,
- filter: None,
- filter_selected: false,
- dirty: dirty,
- dirty_meta: dirty_meta,
- };
-
- files.sort();
-
+ let len = files.len();
+ let mut files = Files::default();
+ files.directory = File::new_from_path(&path, None)?;
+ files.len = len;
+ files.dirty_meta = dirty_meta;
- if files.files.len() == 0 {
- files.files = vec![File::new_placeholder(&path)?];
- }
Ok(files)
}
@@ -351,9 +363,12 @@ impl Files {
})?;
}
- let mut files = Files {
+ let len = files.len();
+
+ let files = Files {
directory: File::new_from_path(&path, None)?,
files: files,
+ len: len,
pending_events: Arc::new(RwLock::new(vec![])),
refresh: None,
meta_upto: None,
@@ -367,15 +382,13 @@ impl Files {
dirty_meta: dirty_meta,
};
- files.sort();
-
- if files.files.len() == 0 {
- files.files = vec![File::new_placeholder(&path)?];
- }
-
Ok(files)
}
+ pub fn recalculate_len(&mut self) {
+ self.len = self.iter_files().count();
+ }
+
pub fn get_file_mut(&mut self, index: usize) -> Option<&mut File> {
self.iter_files_mut()
.nth(index)
@@ -511,13 +524,19 @@ impl Files {
if self.show_hidden == true && self.len() > 1 {
self.remove_placeholder();
+ } else {
+ // avoid doing this twice, since remove_placeholder() does it too
+ self.recalculate_len();
}
}
fn remove_placeholder(&mut self) {
let dirpath = self.directory.path.clone();
self.find_file_with_path(&dirpath).cloned()
- .map(|placeholder| self.files.remove_item(&placeholder));
+ .map(|placeholder| {
+ self.files.remove_item(&placeholder);
+ self.recalculate_len();
+ });
}
pub fn ready_to_refresh(&self) -> HResult<bool> {
@@ -532,6 +551,9 @@ impl Files {
refresh.pull_async()?;
let mut refresh = refresh.value?;
self.files = refresh.new_files.take()?;
+ if refresh.new_len != self.len() {
+ self.len = refresh.new_len;
+ }
return Ok(Some(refresh));
} else {
self.refresh.replace(refresh);
@@ -658,6 +680,7 @@ impl Files {
if self.len() == 0 {
let placeholder = File::new_placeholder(&self.directory.path).unwrap();
self.files.push(placeholder);
+ self.len = 1;
}
self.set_dirty();
@@ -672,7 +695,7 @@ impl Files {
}
pub fn len(&self) -> usize {
- self.iter_files().count()
+ self.len
}
pub fn get_selected(&self) -> impl Iterator<Item=&File> {
diff --git a/src/fscache.rs b/src/fscache.rs
index 7f4ce24..9fbc1e8 100644
--- a/src/fscache.rs
+++ b/src/fscache.rs
@@ -176,6 +176,7 @@ impl FsCache {
cache.fs_event_dispatcher.add_target(&dir,
&files.pending_events).log();
FsCache::apply_settingss(&cache, &mut files).ok();
+ files.sort();
Ok(files)
});
Ok((selection, files))
@@ -184,8 +185,7 @@ impl FsCache {
pub fn get_files_sync(&self, dir: &File) -> HResult<Files> {
let files = self.get_files(&dir, Stale::new())?.1;
- let mut files = files.run_sync()?;
- FsCache::apply_settingss(&self, &mut files).ok();
+ let files = files.run_sync()?;
let files = FsCache::ensure_not_empty(files)?;
Ok(files)
}
@@ -268,7 +268,6 @@ impl FsCache {
}
}
- files.sort();
let files = FsCache::ensure_not_empty(files)?;
Ok(files)
});
@@ -285,6 +284,12 @@ impl FsCache {
if tab_settings.is_none() { return Ok(()) }
let tab_settings = tab_settings?;
+ if files.show_hidden != tab_settings.dir_settings.show_hidden ||
+ files.filter != tab_settings.dir_settings.filter ||
+ files.filter_selected != tab_settings.dir_settings.filter_selected {
+ files.recalculate_len();
+ }
+
files.sort = tab_settings.dir_settings.sort;
files.dirs_first = tab_settings.dir_settings.dirs_first;
files.reverse = tab_settings.dir_settings.reverse;
@@ -292,6 +297,8 @@ impl FsCache {
files.filter = tab_settings.dir_settings.filter.clone();
files.filter_selected = tab_settings.dir_settings.filter_selected;
+
+
if tab_settings.multi_selections.len() > 0 {
for file in &mut files.files {
for selected_files in &tab_settings.multi_selections {
@@ -302,7 +309,6 @@ impl FsCache {
}
}
- files.sort();
Ok(())
}
@@ -311,6 +317,7 @@ impl FsCache {
let path = &files.directory.path;
let placeholder = File::new_placeholder(&path)?;
files.files.push(placeholder);
+ files.len = 1;
}
Ok(files)
}
diff --git a/src/listview.rs b/src/listview.rs
index c744f4f..be27dd8 100644
--- a/src/listview.rs
+++ b/src/listview.rs
@@ -707,7 +707,7 @@ impl<T> Widget for ListView<T> where ListView<T>: Listable {
self.selection = self.buffer.len() - 1;
}
- if self.core.is_dirty() || buffer_len != self.len() {
+ if self.core.is_dirty() {
self.buffer = self.render();
self.core.set_clean();
}