use std::fmt::Debug;
use std::path::PathBuf;
use termion::event::Key;
use unicode_width::UnicodeWidthStr;
use rayon::prelude::*;
use async_value::Stale;
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;
fn len(&self) -> usize;
fn render(&self) -> Vec<String>;
fn render_header(&self) -> HResult<String> { Ok("".to_string()) }
fn render_footer(&self) -> HResult<String> { Ok("".to_string()) }
fn on_new(&mut self) -> HResult<()> { Ok(()) }
fn on_refresh(&mut self) -> HResult<()> { Ok(()) }
fn on_key(&mut self, _key: Key) -> HResult<()> { Ok(()) }
}
use crate::keybind::{Acting, Bindings, FileListAction, Movement};
impl Acting for ListView<Files> {
type Action=FileListAction;
fn search_in(&self) -> Bindings<Self::Action> {
self.core.config().keybinds.filelist
}
fn movement(&mut self, movement: &Movement) -> HResult<()> {
use Movement::*;
let pos = self.get_selection();
match movement {
Up(n) => { for _ in 0..*n { self.move_up(); }; self.refresh()?; }
Down(n) => { for _ in 0..*n { self.move_down(); }; self.refresh()?; }
PageUp => self.page_up(),
PageDown => self.page_down(),
Top => self.move_top(),
Bottom => self.move_bottom(),
Left | Right => {}
}
if pos != self.get_selection() {
self.update_selected_file(pos);
}
Ok(())
}
fn do_action(&mut self, action: &Self::Action) -> HResult<()> {
use FileListAction::*;
match action {
Search => self.search_file()?,
SearchNext => self.search_next()?,
SearchPrev => self.search_prev()?,
Filter => self.filter()?,
Select => self.multi_select_file(),
InvertSelection => self.invert_selection(),
ClearSelection => self.clear_selections(),
FilterSelection => self.toggle_filter_selected(),
ToggleTag => self.toggle_tag()?,
ToggleHidden => self.toggle_hidden(),
ReverseSort => self.reverse_sort(),
CycleSort => self.cycle_sort(),
ToNextMtime => self.select_next_mtime(),
ToPrevMtime => self.select_prev_mtime(),
ToggleDirsFirst => self.toggle_dirs_first(),
}
Ok(())
}
}
impl Listable for ListView<Files> {
type Item = File;
fn len(&self) -> usize {
self.content.len()
}
fn render(&self)-> Vec<String> {
self.render()
}
fn on_new(&mut self) -> HResult<()> {
let show_hidden = self.core.config().show_hidden();
self.content.show_hidden = show_hidden;
Ok(())
}
fn on_refresh(&mut self) -> HResult<()> {
if self.content.len() == 0 {
let path = &self.content.directory.path;
let placeholder = File::new_placeholde