summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2020-01-26 01:31:29 +0100
committerrabite <rabite@posteo.de>2020-01-26 01:31:29 +0100
commit428879e184b4a2160e3a12dbf2f95f10d8cb5b0a (patch)
treeffc8748d005e7938b8fa748b5c6128e58aaa6d4c
parente2ce6e02554137496d6539269e700b99344493a2 (diff)
add builder for ListView<Files>
-rw-r--r--Cargo.lock6
-rw-r--r--Cargo.toml2
-rw-r--r--src/fscache.rs7
-rw-r--r--src/listview.rs160
4 files changed, 168 insertions, 7 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 0cb3a72..bbee8dd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -63,7 +63,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "async_value"
-version = "0.2.5"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -580,7 +580,7 @@ name = "hunter"
version = "1.3.5"
dependencies = [
"alphanumeric-sort 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "async_value 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "async_value 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1556,7 +1556,7 @@ dependencies = [
"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9"
"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
-"checksum async_value 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70c539659e43174b12194af36cda1859266a5dcad90d87bafe80e25f49666140"
+"checksum async_value 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "35a62a04436ffd962e78a3301658eac900480d425ea36ec42553aadc572742be"
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
diff --git a/Cargo.toml b/Cargo.toml
index d6c9472..48080c6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -32,7 +32,7 @@ parse-ansi = "0.1.6"
signal-notify = "0.1.3"
systemstat = "0.1.5"
mime_guess = "2.0"
-async_value = "0.2.5"
+async_value = "0.2.6"
osstrtools = "0.2"
pathbuftools = "0.1"
clap = "2.33"
diff --git a/src/fscache.rs b/src/fscache.rs
index bf5ab2f..613bd3e 100644
--- a/src/fscache.rs
+++ b/src/fscache.rs
@@ -183,6 +183,13 @@ impl FsCache {
}
}
+ pub fn get_files_sync_stale(&self, dir: &File, stale: Stale) -> HResult<Files> {
+ let files = self.get_files(&dir, stale)?.1;
+ let files = files.run_sync()?;
+ let files = FsCache::ensure_not_empty(files)?;
+ Ok(files)
+ }
+
pub fn get_files_sync(&self, dir: &File) -> HResult<Files> {
let files = self.get_files(&dir, Stale::new())?.1;
let files = files.run_sync()?;
diff --git a/src/listview.rs b/src/listview.rs
index 8a14d54..134f9b0 100644
--- a/src/listview.rs
+++ b/src/listview.rs
@@ -1,14 +1,18 @@
use std::fmt::Debug;
+use std::path::{Path, PathBuf};
+
use termion::event::Key;
use unicode_width::UnicodeWidthStr;
-use std::path::{Path, PathBuf};
+use async_value::{Stale, StopIter};
use crate::files::{File, Files};
use crate::fail::{HResult, HError, ErrorLog};
use crate::term;
use crate::widget::{Widget, WidgetCore};
use crate::dirty::Dirtyable;
+use crate::fscache::FsCache;
+
pub trait Listable {
type Item: Debug + PartialEq + Default;
@@ -253,8 +257,125 @@ where
}
+pub enum FileSource {
+ Path(File),
+ Files(Files)
+}
+
+
+pub struct FileListBuilder {
+ core: WidgetCore,
+ source: FileSource,
+ cache: Option<crate::fscache::FsCache>,
+ selected_file: Option<File>,
+ stale: Option<Stale>,
+ meta_upto: usize,
+ meta_all: bool,
+ prerender: bool
+}
+
+impl FileListBuilder {
+ pub fn new(core: WidgetCore, source: FileSource) -> Self {
+ FileListBuilder {
+ core: core,
+ source: source,
+ cache: None,
+ selected_file: None,
+ stale: None,
+ meta_upto: 0,
+ meta_all: false,
+ prerender: false
+ }
+ }
+
+ pub fn select(mut self, file: impl Into<Option<File>>) -> Self {
+ self.selected_file = file.into();
+ self
+ }
+
+ pub fn with_cache(mut self, cache: impl Into<Option<FsCache>>) -> Self {
+ self.cache = cache.into();
+ self
+ }
+
+ pub fn with_stale(mut self, stale: impl Into<Option<Stale>>) -> Self {
+ self.stale = stale.into();
+ self
+ }
+
+ pub fn meta_upto(mut self, upto: impl Into<Option<usize>>) -> Self {
+ self.meta_upto = upto.into().unwrap_or(0);
+ self
+ }
+
+ pub fn meta_all(mut self) -> Self {
+ self.meta_all = true;
+ self
+ }
+
+ pub fn prerender(mut self) -> Self {
+ self.prerender = true;
+ self
+ }
+
+ pub fn build(self) -> HResult<ListView<Files>> {
+ let c = &self.cache;
+ let s = self.stale.clone();
+ let mut 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)))
+ }
+ }?;
+
+ if self.meta_all {
+ files.meta_all();
+ } else if self.meta_upto > 0 {
+ files.meta_upto(self.meta_upto, Some(self.core.get_sender()));
+ }
+
+ let selected_file = match self.selected_file {
+ Some(f) => Some(f),
+ None => {
+ c.as_ref()
+ .map(|c| c.get_selection(&files.directory).ok())
+ .flatten()
+ }
+ };
+
+ let mut view = ListView::new(&self.core, files);
+
+ selected_file.map(|mut f| {
+ f.meta_sync().log();
+ view.select_file(&f);
+ });
+
+ if self.prerender {
+ view.refresh().log();
+
+
+ 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;
+ }
+ };
+
+ Ok(view)
+ }
+}
+
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;
@@ -327,12 +448,13 @@ impl ListView<Files>
}
pub fn select_file(&mut self, file: &File) {
- self.current_item = Some(file.clone());
+ let file = file.clone();
+ self.current_item = Some(file);
let pos = self
.content
.iter_files()
- .position(|item| item == file)
+ .position(|item| item == self.selected_file())
.unwrap_or(0);
self.set_selection(pos);
}
@@ -719,6 +841,38 @@ 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(())
+ }
+ }
+
fn refresh_files(&mut self) -> HResult<()> {
if let Ok(Some(mut refresh)) = self.content.get_refresh() {
let file = self.clone_selected_file();