summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fail.rs9
-rw-r--r--src/file_browser.rs92
-rw-r--r--src/files.rs54
-rw-r--r--src/listview.rs165
-rw-r--r--src/preview.rs8
5 files changed, 187 insertions, 141 deletions
diff --git a/src/fail.rs b/src/fail.rs
index 38a66d0..1abdea7 100644
--- a/src/fail.rs
+++ b/src/fail.rs
@@ -30,6 +30,8 @@ pub enum HError {
ChannelRecvError{#[cause] error: std::sync::mpsc::RecvError},
#[fail(display = "Channel failed")]
ChannelSendError,
+ #[fail(display = "Timer ran out while waiting for message on channel!")]
+ ChannelRecvTimeout(#[cause] std::sync::mpsc::RecvTimeoutError),
#[fail(display = "Previewer failed on file: {}", file)]
PreviewFailed{file: String},
#[fail(display = "StalePreviewer for file: {}", file)]
@@ -292,6 +294,13 @@ impl From<std::sync::mpsc::RecvError> for HError {
}
}
+impl From<std::sync::mpsc::RecvTimeoutError> for HError {
+ fn from(error: std::sync::mpsc::RecvTimeoutError) -> Self {
+ let err = HError::ChannelRecvTimeout(error);
+ err
+ }
+}
+
impl<T> From<std::sync::mpsc::SendError<T>> for HError {
fn from(_error: std::sync::mpsc::SendError<T>) -> Self {
let err = HError::ChannelSendError;
diff --git a/src/file_browser.rs b/src/file_browser.rs
index 9361dce..66d6dc6 100644
--- a/src/file_browser.rs
+++ b/src/file_browser.rs
@@ -199,7 +199,6 @@ impl Tabbable for TabView<FileBrowser> {
w.as_mut()
.map(|mut w| {
w.content.show_hidden = show_hidden;
- w.content.dirty_meta.set_dirty();
w.refresh().log();
}).ok();
Ok(())
@@ -211,7 +210,6 @@ impl Tabbable for TabView<FileBrowser> {
w.as_mut()
.map(|mut w| {
w.content.show_hidden = show_hidden;
- w.content.dirty_meta.set_dirty();
w.refresh().log();
}).ok();
Ok(())
@@ -262,7 +260,7 @@ impl FileBrowser {
let source = FileSource::Path(dir);
ListView::builder(core_m, source)
.meta_all()
- .prerender()
+ // .prerender()
.with_cache(cache)
.with_stale(stale.clone())
.build()
@@ -274,8 +272,8 @@ impl FileBrowser {
let dir = File::new_from_path(&left_path, None)?;
let source = FileSource::Path(dir);
ListView::builder(core_l, source)
- .meta_all()
- .prerender()
+ // .meta_all()
+ // .prerender()
.with_cache(cache)
.with_stale(stale.clone())
.build()
@@ -359,7 +357,7 @@ impl FileBrowser {
ListView::builder(core, source)
.meta_all()
- .prerender()
+ // .prerender()
.with_cache(cache)
.with_stale(stale.clone())
.build()
@@ -476,19 +474,19 @@ impl FileBrowser {
self.prev_cwd = Some(self.cwd.clone());
self.cwd = dir.clone();
- let file_source = FileSource::Path(self.cwd.clone());
+ let file_source = FileSource::Path(self.cwd.clone());
- let main_async_widget = self.main_async_widget_mut()?;
- main_async_widget.change_to(move |stale: &Stale, core| {
- let view = ListView::builder(core, file_source)
- .meta_all()
- .prerender()
- .with_cache(cache)
- .with_stale(stale.clone())
- .build()?;
+ let main_async_widget = self.main_async_widget_mut()?;
+ main_async_widget.change_to(move |stale: &Stale, core| {
+ let view = ListView::builder(core, file_source)
+ .meta_all()
+ // .prerender()
+ .with_cache(cache)
+ .with_stale(stale.clone())
+ .build()?;
- Ok(view)
- }).log();
+ Ok(view)
+ }).log();
if let Ok(grand_parent) = self.cwd()?.parent_as_file() {
@@ -499,32 +497,36 @@ impl FileBrowser {
}).log();
}
+ self.preview_widget_mut()
+ .map(|p| p.set_stale())
+ .ok();
+
Ok(())
}
pub fn left_widget_goto(&mut self, dir: &File) -> HResult<()> {
- // Check if we're in the correct directory already and return
- // if we are
- let left_dir = &self.left_widget()?.content.directory;
- if self.left_widget().is_ok() && left_dir == dir {
- return Ok(());
- }
-
- let cache = self.fs_cache.clone();
- let file_source = FileSource::Path(dir.clone());
- let left_async_widget = self.left_async_widget_mut()?;
- left_async_widget.change_to(move |stale, core| {
- let view = ListView::builder(core, file_source)
- .meta_all()
- .prerender()
- .with_cache(cache)
- .with_stale(stale.clone())
- .build()?;
-
- Ok(view)
- }).log();
-
- Ok(())
+ // Check if we're in the correct directory already and return
+ // if we are
+ let left_dir = &self.left_widget()?.content.directory;
+ if self.left_widget().is_ok() && left_dir == dir {
+ return Ok(());
+ }
+
+ let cache = self.fs_cache.clone();
+ let file_source = FileSource::Path(dir.clone());
+ let left_async_widget = self.left_async_widget_mut()?;
+ left_async_widget.change_to(move |stale, core| {
+ let view = ListView::builder(core, file_source)
+ // .meta_all()
+ // .prerender()
+ .with_cache(cache)
+ .with_stale(stale.clone())
+ .build()?;
+
+ Ok(view)
+ }).log();
+
+ Ok(())
}
pub fn go_back(&mut self) -> HResult<()> {
@@ -548,7 +550,7 @@ impl FileBrowser {
ListView::builder(core, file_source)
.select(main_selection)
.meta_all()
- .prerender()
+ // .prerender()
.with_cache(cache)
.with_stale(stale.clone())
.build()
@@ -559,7 +561,7 @@ impl FileBrowser {
let cache = self.fs_cache.clone();
self.left_async_widget_mut()?.change_to(move |stale, core| {
ListView::builder(core, file_source)
- .prerender()
+ // .prerender()
.with_cache(cache)
.with_stale(stale.clone())
.build()
@@ -698,16 +700,16 @@ impl FileBrowser {
pub fn take_main_files(&mut self) -> HResult<Files> {
let mut w = self.main_widget_mut()?;
- w.lines = 0;
- w.buffer.clear();
+ w.content.len = 0;
+ //w.buffer.clear();
let files = std::mem::take(&mut w.content);
Ok(files)
}
pub fn take_left_files(&mut self) -> HResult<Files> {
let mut w = self.left_widget_mut()?;
- w.lines = 0;
- w.buffer.clear();
+ w.content.len = 0;
+ //w.buffer.clear();
let files = std::mem::take(&mut w.content);
Ok(files)
}
diff --git a/src/files.rs b/src/files.rs
index c7d250a..78741c1 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -8,6 +8,7 @@ use std::sync::{Arc, Mutex, RwLock};
use std::sync::mpsc::Sender;
use std::hash::{Hash, Hasher};
use std::str::FromStr;
+use std::sync::atomic::{AtomicU32, Ordering};
use lscolors::LsColors;
use tree_magic;
@@ -157,8 +158,6 @@ impl RefreshPackage {
for event in events.into_iter() {
match event {
Create(mut file) => {
- let dirty_meta = files.dirty_meta.clone();
- file.dirty_meta = Some(dirty_meta);
file.meta_sync().log();
new_files.push(file);
}
@@ -251,7 +250,6 @@ pub struct Files {
pub filter: Option<String>,
pub filter_selected: bool,
pub dirty: DirtyBit,
- pub dirty_meta: AsyncDirtyBit,
}
impl Index<usize> for Files {
@@ -294,7 +292,6 @@ impl Default for Files {
filter: None,
filter_selected: false,
dirty: DirtyBit::new(),
- dirty_meta: AsyncDirtyBit::new(),
}
}
}
@@ -325,8 +322,6 @@ impl Files {
let mut files = Files::default();
files.directory = File::new_from_path(&path, None)?;
files.len = len;
- files.dirty_meta = dirty_meta;
-
Ok(files)
}
@@ -371,7 +366,6 @@ impl Files {
filter: None,
filter_selected: false,
dirty: dirty,
- dirty_meta: dirty_meta,
};
Ok(files)
@@ -418,6 +412,7 @@ impl Files {
(!filter_selected || f.selected))
.filter(move |(_,f)| !(!show_hidden && f.hidden))
}
+
pub fn iter_files(&self) -> impl Iterator<Item=&File> {
let filter = self.filter.clone();
let filter_selected = self.filter_selected;
@@ -761,13 +756,14 @@ impl std::default::Default for File {
}
+
#[derive(Clone)]
pub struct File {
pub name: String,
pub path: PathBuf,
pub hidden: bool,
pub kind: Kind,
- pub dirsize: Option<usize>,
+ pub dirsize: Option<Arc<AtomicU32>>,
pub target: Option<PathBuf>,
pub color: Option<lscolors::Color>,
pub meta: Option<Metadata>,
@@ -882,14 +878,27 @@ impl File {
self.meta = Some(meta);
self.process_meta().log();
- if self.is_dir() {
- let dirsize = std::fs::read_dir(&self.path)?.count();
- self.dirsize = Some(dirsize);
- }
+ // if self.is_dir() {
+ // let dirsize = std::fs::read_dir(&self.path)?.count();
+ // self.dirsize = Some(dirsize);
+ // }
Ok(())
}
+ pub fn run_dirsize(&mut self) {
+ let dirsize = Arc::new(AtomicU32::new(0));
+ self.dirsize = Some(dirsize.clone());
+ let path = self.path.clone();
+ rayon::spawn(move || {
+ std::fs::read_dir(&path)
+ .map(|dirs| {
+ let size = dirs.count();
+ dirsize.store(size as u32, Ordering::Release);
+ });
+ });
+ }
+
pub fn meta(&self) -> Option<&Metadata> {
self.meta.as_ref()
}
@@ -921,8 +930,13 @@ impl File {
}
pub fn calculate_size(&self) -> HResult<(u32, &str)> {
- if let Some(ref dirsize) = self.dirsize {
- return Ok((*dirsize as u32, ""))
+ if self.is_dir() {
+ let size = match self.dirsize {
+ Some(ref size) => (size.load(Ordering::Acquire), ""),
+ None => (0, ""),
+ };
+
+ return Ok(size);
}
@@ -966,6 +980,18 @@ impl File {
tree_magic::match_filepath("text/plain", &self.path)
}
+ pub fn is_filtered(&self, filter: &str, filter_selected: bool) -> bool {
+ self.kind == Kind::Placeholder ||
+ !(// filter.is_some() &&
+ !self.name.contains(filter// .as_ref().unwrap()
+ )) &&
+ (!filter_selected || self.selected)
+ }
+
+ pub fn is_hidden(&self) -> bool {
+ self.hidden
+ }
+
pub fn parent(&self) -> Option<PathBuf> {
Some(self.path.parent()?.to_path_buf())
diff --git a/src/listview.rs b/src/listview.rs
index 6084f98..db08908 100644
--- a/src/listview.rs
+++ b/src/listview.rs
@@ -147,10 +147,10 @@ where
{
pub content: T,
pub current_item: Option<<ListView<T> as Listable>::Item>,
- pub lines: usize,
+ // pub lines: usize,
selection: usize,
pub offset: usize,
- pub buffer: Vec<String>,
+ //pub buffer: Vec<String>,
pub core: WidgetCore,
seeking: bool,
searching: Option<String>,
@@ -165,10 +165,10 @@ where
let mut view = ListView::<T> {
content: content,
current_item: None,
- lines: 0,
+ // lines: 0,
selection: 0,
offset: 0,
- buffer: Vec::new(),
+ // buffer: Vec::new(),
core: core.clone(),
seeking: false,
searching: None
@@ -190,10 +190,10 @@ where
self.seeking = false;
}
pub fn move_down(&mut self) {
- let lines = self.lines;
+ let lines = self.len();
let y_size = self.get_coordinates().unwrap().ysize() as usize;
- if self.lines == 0 || self.selection == lines - 1 {
+ if lines == 0 || self.selection == lines - 1 {
return;
}
@@ -210,7 +210,7 @@ where
}
pub fn move_bottom(&mut self) {
- let lines = self.lines;
+ let lines = self.len();
self.set_selection(lines - 1);
}
@@ -354,22 +354,27 @@ impl FileListBuilder {
.skip(from)
.take(upto)
.par_bridge()
- .for_each(|f| f.meta_sync().log());
- view.content.meta_upto = Some(view.content.len);
+ .for_each(|f| {
+ f.meta_sync().log();
+ if f.is_dir() {
+ f.run_dirsize();
+ }
+ });
+ view.content.meta_upto = Some(upto);
- if self.prerender {
- match self.stale {
- Some(s) => view.render_buffer_stale(s)?,
- None => view.render_buffer()?
- }
+ // if self.prerender {
+ // match self.stale {
+ // Some(s) => view.render_buffer_stale(s)?,
+ // None => view.render_buffer()?
+ // }
- if view.buffer.len() > 0 {
- view.lines = view.buffer.len() - 1;
- }
- };
+ // if view.buffer.len() > 0 {
+ // view.lines = view.buffer.len() - 1;
+ // }
+ // };
view.content.set_clean();
- view.content.dirty_meta.set_clean();
+ // view.content.dirty_meta.set_clean();
view.core.set_clean();
Ok(view)
@@ -565,9 +570,9 @@ impl ListView<Files>
file.toggle_selection();
if !self.content.filter_selected {
- let selection = self.get_selection();
- let line = self.render_line(&file);
- self.buffer[selection] = line;
+ //let selection = self.get_selection();
+ //let line = self.render_line(&file);
+ //self.buffer[selection] = line;
self.move_down();
} else {
@@ -607,12 +612,12 @@ impl ListView<Files>
self.selected_file_mut().toggle_tag()?;
// Create a mutable clone to render changes into buffer
- let mut file = self.clone_selected_file();
- file.toggle_tag()?;
+ // let mut file = self.clone_selected_file();
+ // file.toggle_tag()?;
- let line = self.render_line(&file);
- let selection = self.get_selection();
- self.buffer[selection] = line;
+ // let line = self.render_line(&file);
+ // let selection = self.get_selection();
+ // self.buffer[selection] = line;
self.move_down();
Ok(())
@@ -868,60 +873,66 @@ impl ListView<Files>
fn render(&self) -> Vec<String> {
let render_fn = self.render_line_fn();
+ let ysize = self.get_coordinates().unwrap().ysize_u();
self.content
.iter_files()
+ .skip(self.offset)
+ .take(ysize+1)
+ // .collect::<Vec<_>>()
+ // .into_par_iter()
.map(|file| render_fn(file))
.collect()
}
fn render_buffer(&mut self) -> HResult<()> {
- let render_fn = self.render_line_fn();
- self.buffer = self.content
- .iter_files()
- .enumerate()
- .map(|(_, file)| {
- render_fn(file)
- })
- .collect();
+ // let render_fn = self.render_line_fn();
+ // self.buffer = self.content
+ // .iter_files()
+ // .enumerate()
+ // .map(|(_, file)| {
+ // render_fn(file)
+ // })
+ // .collect();
Ok(())
}
fn render_buffer_stale(&mut self, stale: Stale) -> HResult<()> {
- let render_fn = self.render_line_fn();
- let buffer = self.content
- .iter_files()
- .stop_stale(stale.clone())
- .enumerate()
- .map(|(_, file)| {
- render_fn(file)
- })
- .collect();
-
- if stale.is_stale()
- .unwrap_or(true) {
- return HError::stale();
- } else {
- self.buffer = buffer;
- return Ok(())
- }
+ // let render_fn = self.render_line_fn();
+ // let buffer = self.content
+ // .iter_files()
+ // .stop_stale(stale.clone())
+ // .enumerate()
+ // .map(|(_, file)| {
+ // render_fn(file)
+ // })
+ // .collect();
+
+ // if stale.is_stale()
+ // .unwrap_or(true) {
+ // return HError::stale();
+ // } else {
+ // self.buffer = buffer;
+ // return Ok(())
+ // }
+ Ok(())
}
fn refresh_files(&mut self) -> HResult<()> {
- if let Ok(Some(mut refresh)) = self.content.get_refresh() {
- let file = self.clone_selected_file();
+ // if let Ok(Some(mut refresh)) = self.content.get_refresh() {
+ // let file = self.clone_selected_file();
- self.buffer = refresh.new_buffer.take()?;
- self.lines = self.buffer.len() - 1;
+ // self.buffer = refresh.new_buffer.take()?;
+ // self.lines = self.buffer.len() - 1;
- self.select_file(&file);
- }
+ // self.select_file(&file);
+ // }
- if self.content.ready_to_refresh()? {
- let render_fn = self.render_line_fn();
- self.content.process_fs_events(self.buffer.clone(),
- self.core.get_sender(),
- render_fn)?;
- }
+ // if self.content.ready_to_refresh()? {
+ // let render_fn = self.render_line_fn();
+ // self.content.process_fs_events(self.buffer.clone(),
+ // self.core.get_sender(),
+ // render_fn)?;
+ // }
Ok(())
}
@@ -941,18 +952,18 @@ where
fn refresh(&mut self) -> HResult<()> {
self.on_refresh().log();
- let buffer_len = self.buffer.len();
+ // let buffer_len = self.buffer.len();
- self.lines = buffer_len;
+ // self.lines = buffer_len;
- if self.selection >= self.buffer.len() && self.buffer.len() != 0 {
- self.selection = self.buffer.len() - 1;
+ if self.selection >= self.len() && self.len() != 0 {
+ self.selection = self.len() - 1;
}
- if self.core.is_dirty() {
- self.buffer = self.render();
- self.core.set_clean();
- }
+ // if self.core.is_dirty() {
+ // self.buffer = self.render();
+ // self.core.set_clean();
+ // }
Ok(())
}
@@ -967,13 +978,11 @@ where
fn get_drawlist(&self) -> HResult<String> {
let mut output = term::reset();
let (xpos, ypos) = self.get_coordinates().unwrap().position().position();
- let ysize = self.get_coordinates().unwrap().ysize() as usize;
- output += &self
- .buffer
+ let render = self.render();
+
+ output += &render
.iter()
- .skip(self.offset)
- .take(ysize)
.enumerate()
.map(|(i, item)| {
let mut output = term::normal_color();
@@ -991,7 +1000,7 @@ where
})
.collect::<String>();
- output += &self.get_redraw_empty_list(self.buffer.len())?;
+ output += &self.get_redraw_empty_list(self.len())?;
Ok(output)
}
diff --git a/src/preview.rs b/src/preview.rs
index cc50168..0b27176 100644
--- a/src/preview.rs
+++ b/src/preview.rs
@@ -65,7 +65,7 @@ pub struct AsyncWidget<W: Widget + Send + 'static> {
impl<W: Widget + Send + 'static> AsyncWidget<W> {
pub fn new(core: &WidgetCore,
- closure: impl FnOnce(&Stale) -> HResult<W> + Send + Sync + 'static)
+ closure: impl FnOnce(&Stale) -> HResult<W> + Send + 'static)
-> AsyncWidget<W> {
let sender = Arc::new(Mutex::new(core.get_sender()));
let mut widget = Async::new(move |stale|
@@ -86,7 +86,7 @@ impl<W: Widget + Send + 'static> AsyncWidget<W> {
pub fn change_to(&mut self,
closure: impl FnOnce(&Stale,
WidgetCore)
- -> HResult<W> + Send + Sync + 'static)
+ -> HResult<W> + Send + 'static)
-> HResult<()> {
self.set_stale().log();
@@ -327,7 +327,7 @@ impl Previewer {
let source = crate::listview::FileSource::Files(files);
let list = ListView::builder(core.clone(), source)
- .prerender()
+ // .prerender()
.with_cache(cache)
.with_stale(stale.clone())
.select(selected_file)
@@ -457,7 +457,7 @@ impl Previewer {
let source = FileSource::Path(file.clone());
let mut file_list = ListView::builder(core.clone(), source)
- .prerender()
+ // .prerender()
.with_cache(cache)
.with_stale(stale.clone())
.build()?;