summaryrefslogtreecommitdiffstats
path: root/src/listview.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/listview.rs')
-rw-r--r--src/listview.rs290
1 files changed, 107 insertions, 183 deletions
diff --git a/src/listview.rs b/src/listview.rs
index 8913390..13f5ba6 100644
--- a/src/listview.rs
+++ b/src/listview.rs
@@ -1,11 +1,11 @@
use std::fmt::Debug;
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
use termion::event::Key;
use unicode_width::UnicodeWidthStr;
use rayon::prelude::*;
-use async_value::{Stale, StopIter};
+use async_value::Stale;
use crate::files::{File, Files};
use crate::fail::{HResult, HError, ErrorLog};
@@ -103,17 +103,6 @@ impl Listable for ListView<Files> {
fn on_new(&mut self) -> HResult<()> {
let show_hidden = self.core.config().show_hidden();
self.content.show_hidden = show_hidden;
- let mut file = self.content
- .iter_files()
- .nth(0)
- .cloned()
- .unwrap_or_default();
-
- if file.meta.is_none() {
- file.meta_sync().log();
- }
-
- self.current_item = Some(file);
Ok(())
}
@@ -125,6 +114,17 @@ impl Listable for ListView<Files> {
self.content.len = 1;
}
+ let meta_upto = self.content.meta_upto.unwrap_or(0);
+ let ysize = self.core.coordinates.ysize_u();
+
+ if self.offset + ysize >= meta_upto {
+ let sender = self.core.get_sender();
+ let njobs = self.offset + ysize;
+
+ self.content.enqueue_jobs(njobs);
+ self.content.run_jobs(sender);
+ }
+
self.refresh_files().log();
if self.content.is_dirty() {
@@ -147,10 +147,8 @@ where
{
pub content: T,
pub current_item: Option<<ListView<T> as Listable>::Item>,
- // pub lines: usize,
selection: usize,
pub offset: usize,
- //pub buffer: Vec<String>,
pub core: WidgetCore,
seeking: bool,
searching: Option<String>,
@@ -165,10 +163,8 @@ where
let mut view = ListView::<T> {
content: content,
current_item: None,
- // lines: 0,
selection: 0,
offset: 0,
- // buffer: Vec::new(),
core: core.clone(),
seeking: false,
searching: None
@@ -248,6 +244,7 @@ where
}
+#[derive(PartialEq)]
pub enum FileSource {
Path(File),
Files(Files)
@@ -262,7 +259,6 @@ pub struct FileListBuilder {
stale: Option<Stale>,
meta_upto: usize,
meta_all: bool,
- prerender: bool
}
impl FileListBuilder {
@@ -275,7 +271,6 @@ impl FileListBuilder {
stale: None,
meta_upto: 0,
meta_all: false,
- prerender: false
}
}
@@ -304,77 +299,58 @@ impl FileListBuilder {
self
}
- pub fn prerender(mut self) -> Self {
- self.prerender = true;
- self
- }
+ pub fn build(mut self) -> HResult<ListView<Files>> {
+ // Create new IO pool to not block the main render pool, or other busy IO pools
+ let pool = crate::files::get_pool();
- pub fn build(self) -> HResult<ListView<Files>> {
let c = &self.cache;
let s = self.stale.clone();
- let files = match self.source {
- FileSource::Files(f) => Ok(f),
- FileSource::Path(f) => {
- c.as_ref()
- .map_or_else(| | Files::new_from_path(&f.path),
- |c| s.map_or_else(| | c.get_files_sync(&f),
- |s| c.get_files_sync_stale(&f, s)))
- }
- }?;
-
- let mut view = ListView::new(&self.core, files);
-
- let selected_file = match self.selected_file {
- Some(f) => Some(f),
- None => {
- c.as_ref()
- .map(|c| c.get_selection(&view.content.directory).ok())
- .flatten()
- }
+ let core = self.core;
+ let cfg = core.config();
+ let source = self.source;
+ let selected_file = self.selected_file.take();
+
+ // Already sorted
+ let nosort = match source {
+ FileSource::Files(_) => true,
+ _ => false
};
- selected_file.map(|mut f| {
- f.meta_sync().log();
- view.select_file(&f);
- });
+ let files = pool.install(|| -> HResult<Files> {
+ let mut files = match source {
+ FileSource::Files(f) => Ok(f),
+ FileSource::Path(f) => {
+ c.as_ref()
+ .map_or_else(| | unreachable!(),
+ |c| s.map_or_else(| | c.get_files_sync(&f),
+ |s| c.get_files_sync_stale(&f, s)))
+ }
+ }?;
- let from = match self.meta_all {
- true => 0,
- false => view.offset,
- };
+ // Check/set hidden flag and recalculate number of files if it's different
+ if !files.show_hidden == cfg.show_hidden() {
+ files.show_hidden = cfg.show_hidden();
+ files.recalculate_len();
+ }
- let ysize = view.core.coordinates.ysize_u();
- let upto = match self.meta_all {
- true => view.content.len,
- false => from + ysize + 1
- };
+ // TODO: Fix sorting so it works with lazy/partial sorting
+ if !nosort {
+ files.sort();
+ }
- view.content
- .iter_files_mut()
- .skip(from)
- .take(upto)
- .par_bridge()
- .for_each(|f| {
- f.meta_sync().log();
- if f.is_dir() {
- f.run_dirsize();
- }
- });
- view.content.meta_upto = Some(upto);
+ Ok(files)
+ })?;
- // if self.prerender {
- // match self.stale {
- // Some(s) => view.render_buffer_stale(s)?,
- // None => view.render_buffer()?
- // }
+ let mut view = ListView::new(&core, files);
- // if view.buffer.len() > 0 {
- // view.lines = view.buffer.len() - 1;
- // }
- // };
+ selected_file
+ .or_else(|| c.as_ref()
+ .and_then(|c| c.get_selection(&view.content.directory).ok()))
+ .map(|f| view.select_file(&f));
+ self.stale.map(|s| view.content.stale = Some(s));
+ self.cache.map(|c| view.content.cache = Some(c));
view.content.set_clean();
- // view.content.dirty_meta.set_clean();
view.core.set_clean();
Ok(view)
@@ -386,6 +362,7 @@ impl ListView<Files>
pub fn builder(core: WidgetCore, source: FileSource) -> FileListBuilder {
FileListBuilder::new(core, source)
}
+
pub fn update_selected_file(&mut self) {
let pos = self.selection;
@@ -398,7 +375,10 @@ impl ListView<Files>
}
pub fn selected_file(&self) -> &File {
- self.current_item.as_ref().unwrap()
+ self.current_item
+ .as_ref()
+ .or_else(|| self.content.iter_files().nth(0))
+ .unwrap()
}
pub fn selected_file_mut(&mut self) -> &mut File {
@@ -430,43 +410,39 @@ impl ListView<Files>
self.selected_file().grand_parent()
}
- pub fn goto_grand_parent(&mut self) -> HResult<()> {
- match self.grand_parent() {
- Some(grand_parent) => self.goto_path(&grand_parent),
- None => { self.core.show_status("Can't go further!") },
- }
- }
-
- fn goto_selected(&mut self) -> HResult<()> {
- let path = self.selected_file().path();
-
- self.goto_path(&path)
- }
-
- pub fn goto_path(&mut self, path: &Path) -> HResult<()> {
- match crate::files::Files::new_from_path(path) {
- Ok(files) => {
- self.content = files;
- self.selection = 0;
- self.offset = 0;
- self.refresh()
- }
- Err(err) => {
- self.core.show_status(&format!("Can't open this path: {}", err))
- }
- }
- }
-
pub fn select_file(&mut self, file: &File) {
let file = file.clone();
- self.current_item = Some(file);
- let pos = self
+ let posfile = self
.content
.iter_files()
- .position(|item| item == self.selected_file())
- .unwrap_or(0);
- self.set_selection(pos);
+ .collect::<Vec<&File>>()
+ .into_par_iter()
+ .enumerate()
+ .find_any(|(_, item)| item == &&file);
+
+ match posfile {
+ Some((i, file)) => {
+ self.current_item = Some(file.clone());
+ self.set_selection(i);
+ }
+ // Something went wrong?
+ None => {
+ let dir = &self.content.directory.path;
+ let file = file.path;
+
+ HError::wrong_directory::<()>(dir.clone(),
+ file.clone()).log();
+ let file = self.content
+ .iter_files()
+ .nth(0)
+ .cloned()
+ .or_else(|| File::new_placeholder(dir).ok())
+ .unwrap();
+ self.current_item = Some(file);
+ self.set_selection(0);
+ }
+ }
}
fn cycle_sort(&mut self) {
@@ -570,10 +546,6 @@ 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;
-
self.move_down();
} else {
if self.content.filter_selected && self.content.len() == 0 {
@@ -610,15 +582,6 @@ impl ListView<Files>
fn toggle_tag(&mut self) -> HResult<()> {
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 line = self.render_line(&file);
- // let selection = self.get_selection();
- // self.buffer[selection] = line;
-
self.move_down();
Ok(())
}
@@ -773,6 +736,8 @@ impl ListView<Files>
#[allow(trivial_bounds)]
fn render_line_fn(&self) -> impl Fn(&File) -> String {
use std::fmt::Write;
+ use crate::files::FileError;
+
let xsize = self.get_coordinates().unwrap().xsize();
let icons = self.core.config().icons;
@@ -788,8 +753,13 @@ impl ListView<Files>
let size = file.calculate_size();
let (size, unit) = match size {
- Ok((size, unit)) => (size, unit),
- Err(_) => (0 as u32, "")
+ Ok((size, unit)) => (size.to_string(), unit),
+ Err(HError::FileError(FileError::MetaPending)) => {
+ // Using mod 5 explicitly here for that nice nonlinear look
+ let ticks = crate::files::tick_str();
+ (String::from(ticks), "")
+ },
+ Err(_) => (String::from("ERR"), "")
};
let (tag, tag_len) = match file.is_tagged() {
@@ -834,18 +804,18 @@ impl ListView<Files>
write!(&mut line, "{}", termion::cursor::Save).unwrap();
- match &file.color {
+ match file.get_color() {
Some(color) => write!(&mut line,
"{}{}{}{}{}{:padding$}{}",
tag,
- term::from_lscolor(color),
+ &color,
selection_color,
selection_gap,
icon,
&sized_string,
term::normal_color(),
padding = padding as usize),
- None => write!(&mut line,
+ _ => write!(&mut line,
"{}{}{}{}{}{:padding$}{}",
tag,
term::normal_color(),
@@ -885,55 +855,17 @@ impl ListView<Files>
.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();
- 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(())
- // }
- Ok(())
- }
-
fn refresh_files(&mut self) -> HResult<()> {
- // 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;
+ let file = self.clone_selected_file();
- // self.select_file(&file);
- // }
+ if let Ok(Some(_)) = self.content.get_refresh() {
+ self.select_file(&file);
+ self.content.run_jobs(self.core.get_sender());
+ }
- // 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()? {
+ self.content.process_fs_events(self.core.get_sender())?;
+ }
Ok(())
}
@@ -953,18 +885,10 @@ where
fn refresh(&mut self) -> HResult<()> {
self.on_refresh().log();
- // let buffer_len = self.buffer.len();
-
- // self.lines = buffer_len;
-
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();
- // }
Ok(())
}