summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/fail.rs35
-rw-r--r--src/file_browser.rs176
-rw-r--r--src/files.rs7
-rw-r--r--src/hbox.rs62
-rw-r--r--src/listview.rs116
-rw-r--r--src/main.rs43
-rw-r--r--src/miller_columns.rs80
-rw-r--r--src/minibuffer.rs34
-rw-r--r--src/preview.rs201
-rw-r--r--src/proclist.rs135
-rw-r--r--src/tabview.rs87
-rw-r--r--src/term.rs30
-rw-r--r--src/textview.rs71
-rw-r--r--src/widget.rs327
-rw-r--r--src/window.rs428
15 files changed, 1011 insertions, 821 deletions
diff --git a/src/fail.rs b/src/fail.rs
index ff9ad2e..1c0575b 100644
--- a/src/fail.rs
+++ b/src/fail.rs
@@ -1,5 +1,6 @@
use failure;
use failure::Fail;
+use failure::Backtrace;
use std::path::PathBuf;
@@ -28,21 +29,45 @@ pub enum HError {
#[fail(display = "Was None!")]
NoneError,
#[fail(display = "Not ready yet!")]
- WillBeNotReady,
+ WillBeNotReady(Backtrace),
#[fail(display = "No widget found")]
- NoWidgetError,
+ NoWidgetError(Backtrace),
#[fail(display = "Path: {:?} not in this directory: {:?}", path, dir)]
WrongDirectoryError{ path: PathBuf, dir: PathBuf },
#[fail(display = "Widget finnished")]
PopupFinnished,
- #[fail(display = "Input finnished")]
- InputFinnished,
#[fail(display = "No completions found")]
NoCompletionsError,
#[fail(display = "No more history")]
- NoHistoryError
+ NoHistoryError,
+ #[fail(display = "No core for widget")]
+ NoWidgetCoreError(Backtrace),
+ #[fail(display = "No header for widget")]
+ NoHeaderError,
}
+pub trait ErrorLog where Self: Sized {
+ fn log(self) {}
+}
+
+impl<T> ErrorLog for HResult<T> {
+ fn log(self) {
+ if let Err(err) = self {
+ eprintln!("{:?}", err);
+ }
+ }
+}
+
+
+
+
+// impl From<&HError> for HError {
+// fn from(error: &HError) -> Self {
+// dbg!(&error);
+// (error.clone())
+// }
+// }
+
impl From<std::io::Error> for HError {
fn from(error: std::io::Error) -> Self {
dbg!(&error);
diff --git a/src/file_browser.rs b/src/file_browser.rs
index a950f0a..13533c1 100644
--- a/src/file_browser.rs
+++ b/src/file_browser.rs
@@ -1,22 +1,20 @@
use termion::event::Key;
use notify::{INotifyWatcher, Watcher, DebouncedEvent, RecursiveMode};
-use std::error::Error;
use std::io::Write;
use std::sync::{Arc, Mutex};
-use std::sync::mpsc::{channel, Receiver};
+use std::sync::mpsc::{channel, Receiver, Sender};
use std::time::Duration;
use std::path::PathBuf;
-use crate::coordinates::{Coordinates};
use crate::files::{File, Files};
use crate::listview::ListView;
use crate::miller_columns::MillerColumns;
use crate::widget::Widget;
use crate::tabview::{TabView, Tabbable};
use crate::preview::WillBeWidget;
-use crate::fail::{HResult, HError};
-use crate::window::{Events, send_event};
+use crate::fail::{HResult, HError, ErrorLog};
+use crate::widget::{Events, WidgetCore};
use crate::proclist::ProcView;
@@ -24,6 +22,7 @@ use crate::proclist::ProcView;
pub struct FileBrowser {
pub columns: MillerColumns<WillBeWidget<ListView<Files>>>,
pub cwd: File,
+ core: WidgetCore,
watcher: INotifyWatcher,
watches: Vec<PathBuf>,
dir_events: Arc<Mutex<Vec<DebouncedEvent>>>,
@@ -31,22 +30,24 @@ pub struct FileBrowser {
}
impl Tabbable for TabView<FileBrowser> {
- fn new_tab(&mut self) {
- let mut tab = FileBrowser::new().unwrap();
+ fn new_tab(&mut self) -> HResult<()> {
+ let mut tab = FileBrowser::new_cored(&self.active_tab_().core)?;
let proc_view = self.active_tab_().proc_view.clone();
tab.proc_view = proc_view;
- self.push_widget(tab);
+ self.push_widget(tab)?;
self.active += 1;
+ Ok(())
}
- fn close_tab(&mut self) {
- self.close_tab_();
+ fn close_tab(&mut self) -> HResult<()> {
+ self.close_tab_()
}
- fn next_tab(&mut self) {
+ fn next_tab(&mut self) -> HResult<()> {
self.next_tab_();
+ Ok(())
}
fn get_tab_names(&self) -> Vec<Option<String>> {
@@ -66,18 +67,18 @@ impl Tabbable for TabView<FileBrowser> {
self.active_tab_mut_()
}
- fn on_next_tab(&mut self) {
- self.active_tab_mut().refresh();
+ fn on_next_tab(&mut self) -> HResult<()> {
+ self.active_tab_mut().refresh()
}
- fn on_key_sub(&mut self, key: Key) {
+ fn on_key_sub(&mut self, key: Key) -> HResult<()> {
match key {
Key::Char('!') => {
let tab_dirs = self.widgets.iter().map(|w| w.cwd.clone())
.collect::<Vec<_>>();
- self.widgets[self.active].exec_cmd(tab_dirs).ok();
+ self.widgets[self.active].exec_cmd(tab_dirs)
}
- _ => { self.active_tab_mut().on_key(key).ok(); }
+ _ => { self.active_tab_mut().on_key(key) }
}
}
}
@@ -86,11 +87,13 @@ impl Tabbable for TabView<FileBrowser> {
-fn watch_dir(rx: Receiver<DebouncedEvent>, dir_events: Arc<Mutex<Vec<DebouncedEvent>>>) {
+fn watch_dir(rx: Receiver<DebouncedEvent>,
+ dir_events: Arc<Mutex<Vec<DebouncedEvent>>>,
+ sender: Sender<Events>) {
std::thread::spawn(move || {
for event in rx.iter() {
dir_events.lock().unwrap().push(event);
- send_event(Events::WidgetReady).unwrap();
+ sender.send(Events::WidgetReady).unwrap();
}
});
}
@@ -100,24 +103,23 @@ fn watch_dir(rx: Receiver<DebouncedEvent>, dir_events: Arc<Mutex<Vec<DebouncedEv
impl FileBrowser {
- pub fn new() -> Result<FileBrowser, Box<Error>> {
+ pub fn new_cored(core: &WidgetCore) -> HResult<FileBrowser> {
let cwd = std::env::current_dir().unwrap();
- let coords = Coordinates::new_at(crate::term::xsize(),
- crate::term::ysize() - 2,
- 1,
- 2);
+ let coords = core.coordinates.clone();
+ let core_ = core.clone();
- let mut miller = MillerColumns::new();
- miller.set_coordinates(&coords);
+ let mut miller = MillerColumns::new(core);
+ miller.set_coordinates(&coords)?;
let (_, main_coords, _) = miller.calculate_coordinates();
let main_path: std::path::PathBuf = cwd.ancestors().take(1).map(|path| std::path::PathBuf::from(path)).collect();
- let main_widget = WillBeWidget::new(Box::new(move |_| {
- let mut list = ListView::new(Files::new_from_path(&main_path).unwrap());
- list.set_coordinates(&main_coords);
- list.animate_slide_up();
+ let main_widget = WillBeWidget::new(&core, Box::new(move |_| {
+ let mut list = ListView::new(&core_,
+ Files::new_from_path(&main_path).unwrap());
+ list.set_coordinates(&main_coords).log();
+ list.animate_slide_up().log();
Ok(list)
}));
@@ -129,13 +131,14 @@ impl FileBrowser {
let (tx_watch, rx_watch) = channel();
let watcher = INotifyWatcher::new(tx_watch, Duration::from_secs(2)).unwrap();
- watch_dir(rx_watch, dir_events.clone());
+ watch_dir(rx_watch, dir_events.clone(), core.get_sender());
- let mut proc_view = ProcView::new();
- proc_view.set_coordinates(&coords);
+ let mut proc_view = ProcView::new(core);
+ proc_view.set_coordinates(&coords).log();
Ok(FileBrowser { columns: miller,
cwd: cwd,
+ core: core.clone(),
watcher: watcher,
watches: vec![],
dir_events: dir_events,
@@ -145,16 +148,17 @@ impl FileBrowser {
pub fn enter_dir(&mut self) -> HResult<()> {
let file = self.selected_file()?;
let (_, coords, _) = self.columns.calculate_coordinates();
+ let core = self.core.clone();
match file.read_dir() {
Ok(files) => {
std::env::set_current_dir(&file.path).unwrap();
self.cwd = file.clone();
- let view = WillBeWidget::new(Box::new(move |_| {
+ let view = WillBeWidget::new(&core.clone(), Box::new(move |_| {
let files = files.clone();
- let mut list = ListView::new(files);
- list.set_coordinates(&coords);
- list.animate_slide_up();
+ let mut list = ListView::new(&core, files);
+ list.set_coordinates(&coords).log();
+ list.animate_slide_up().log();
Ok(list)
}));
self.columns.push_widget(view);
@@ -167,12 +171,12 @@ impl FileBrowser {
match status {
Ok(status) =>
self.show_status(&format!("\"{}\" exited with {}",
- "rifle", status)),
+ "rifle", status)).log(),
Err(err) =>
self.show_status(&format!("Can't run this \"{}\": {}",
- "rifle", err))
+ "rifle", err)).log()
- }
+ };
}
}
Ok(())
@@ -185,8 +189,7 @@ impl FileBrowser {
self.cwd = new_cwd;
}
- self.refresh();
- Ok(())
+ self.refresh()
}
pub fn update_preview(&mut self) -> HResult<()> {
@@ -207,10 +210,12 @@ impl FileBrowser {
let cwd = self.selected_file()?.clone();
if let Ok(grand_parent) = cwd.grand_parent_as_file() {
let (coords, _, _) = self.columns.calculate_coordinates();
- let left_view = WillBeWidget::new(Box::new(move |_| {
+ let core = self.core.clone();
+ let left_view = WillBeWidget::new(&self.core, Box::new(move |_| {
let mut view
- = ListView::new(Files::new_from_path(&grand_parent.path)?);
- view.set_coordinates(&coords);
+ = ListView::new(&core,
+ Files::new_from_path(&grand_parent.path)?);
+ view.set_coordinates(&coords).log();
Ok(view)
}));
self.columns.prepend_widget(left_view);
@@ -341,17 +346,19 @@ impl FileBrowser {
let dir = std::path::PathBuf::from(&dir);
let left_dir = std::path::PathBuf::from(&dir);
let (left_coords, main_coords, _) = self.columns.calculate_coordinates();
+ let mcore = self.core.clone();
+ let lcore = self.core.clone();
- let middle = WillBeWidget::new(Box::new(move |_| {
+ let middle = WillBeWidget::new(&self.core, Box::new(move |_| {
let files = Files::new_from_path(&dir.clone())?;
- let mut listview = ListView::new(files);
- listview.set_coordinates(&main_coords);
+ let mut listview = ListView::new(&mcore, files);
+ listview.set_coordinates(&main_coords).log();
Ok(listview)
}));
- let left = WillBeWidget::new(Box::new(move |_| {
+ let left = WillBeWidget::new(&self.core, Box::new(move |_| {
let files = Files::new_from_path(&left_dir.parent()?)?;
- let mut listview = ListView::new(files);
- listview.set_coordinates(&left_coords);
+ let mut listview = ListView::new(&lcore, files);
+ listview.set_coordinates(&left_coords).log();
Ok(listview)
}));
self.columns.push_widget(left);
@@ -373,7 +380,7 @@ impl FileBrowser {
let cmd = self.minibuffer("exec:")?;
- self.show_status(&format!("Running: \"{}\"", &cmd));
+ self.show_status(&format!("Running: \"{}\"", &cmd)).log();
let mut cmd = if file_names.len() == 0 {
cmd.replace("$s", &format!("{}", &filename))
@@ -397,35 +404,28 @@ impl FileBrowser {
}
impl Widget for FileBrowser {
- fn get_coordinates(&self) -> &Coordinates {
- &self.columns.coordinates
- }
- fn set_coordinates(&mut self, coordinates: &Coordinates) {
- self.columns.set_coordinates(coordinates);
- self.proc_view.lock().unwrap().set_coordinates(coordinates);
- self.refresh();
+ fn get_core(&self) -> HResult<&WidgetCore> {
+ Ok(&self.core)
}
- fn render_header(&self) -> String {
- if self.main_widget().is_err() { return "".to_string() }
- let xsize = self.get_coordinates().xsize();
- let file = self.selected_file().unwrap();
+ fn render_header(&self) -> HResult<String> {
+ let xsize = self.get_coordinates()?.xsize();
+ let file = self.selected_file()?;
let name = &file.name;
let color = if file.is_dir() || file.color.is_none() {
crate::term::highlight_color() } else {
crate::term::from_lscolor(file.color.as_ref().unwrap()) };
- let path = file.path.parent().unwrap().to_string_lossy().to_string();
+ let path = file.path.parent()?.to_string_lossy().to_string();
let pretty_path = format!("{}/{}{}", path, &color, name );
let sized_path = crate::term::sized_string(&pretty_path, xsize);
- sized_path
+ Ok(sized_path)
}
- fn render_footer(&self) -> String {
- if self.main_widget().is_err() { return "".to_string() }
- let xsize = self.get_coordinates().xsize();
- let ypos = self.get_coordinates().position().y();
- let file = self.selected_file().unwrap();
+ fn render_footer(&self) -> HResult<String> {
+ let xsize = self.get_coordinates()?.xsize();
+ let ypos = self.get_coordinates()?.position().y();
+ let file = self.selected_file()?;
let permissions = file.pretty_print_permissions().unwrap_or("NOPERMS".into());
let user = file.pretty_user().unwrap_or("NOUSER".into());
@@ -433,8 +433,8 @@ impl Widget for FileBrowser {
let mtime = file.pretty_mtime().unwrap_or("NOMTIME".into());
- let selection = (*self.main_widget().as_ref().unwrap().lock().unwrap()).as_ref().unwrap().get_selection();
- let file_count = (*self.main_widget().unwrap().lock().unwrap()).as_ref().unwrap().content.len();
+ let selection = (*self.main_widget().as_ref().unwrap().lock()?).as_ref()?.get_selection();
+ let file_count = (*self.main_widget()?.lock()?).as_ref()?.content.len();
let file_count = format!("{}", file_count);
let digits = file_count.len();
let file_count = format!("{:digits$}/{:digits$}",
@@ -442,42 +442,44 @@ impl Widget for FileBrowser {
file_count,
digits = digits);
let count_xpos = xsize - file_count.len() as u16;
- let count_ypos = ypos + self.get_coordinates().ysize();
+ let count_ypos = ypos + self.get_coordinates()?.ysize();
- format!("{} {}:{} {} {} {}", permissions, user, group, mtime,
- crate::term::goto_xy(count_xpos, count_ypos), file_count)
+ Ok(format!("{} {}:{} {} {} {}", permissions, user, group, mtime,
+ crate::term::goto_xy(count_xpos, count_ypos), file_count))
}
- fn refresh(&mut self) {
- self.handle_dir_events().ok();
- self.columns.refresh();
+ fn refresh(&mut self) -> HResult<()> {
+ //self.proc_view.lock()?.set_coordinates(self.get_coordinates()?);
+ self.handle_dir_events()?;
+ self.columns.refresh().ok();
self.fix_left().ok();
self.fix_selection().ok();
self.set_cwd().ok();
self.update_watches().ok();
self.update_preview().ok();
+ Ok(())
}
- fn get_drawlist(&self) -> String {
+ fn get_drawlist(&self) -> HResult<String> {
if self.columns.get_left_widget().is_err() {
- self.columns.get_clearlist() + &self.columns.get_drawlist()
+ Ok(self.columns.get_clearlist()? + &self.columns.get_drawlist()?)
} else {
- self.columns.get_drawlist()
+ Ok(self.columns.get_drawlist()?)
}
}
fn on_key(&mut self, key: Key) -> HResult<()> {
match key {
- Key::Char('/') => { self.turbo_cd().ok(); },
- Key::Char('Q') => { self.quit_with_dir().ok(); },
- Key::Right | Key::Char('f') => { self.enter_dir().ok(); },
- Key::Left | Key::Char('b') => { self.go_back().ok(); },
+ Key::Char('/') => { self.turbo_cd()?; },
+ Key::Char('Q') => { self.quit_with_dir()?; },
+ Key::Right | Key::Char('f') => { self.enter_dir()?; },
+ Key::Left | Key::Char('b') => { self.go_back()?; },
Key::Char('w') => {
- self.proc_view.lock()?.popup().ok();
+ self.proc_view.lock()?.popup()?;
}
,
- _ => { self.columns.get_main_widget_mut()?.on_key(key).ok(); },
+ _ => { self.columns.get_main_widget_mut()?.on_key(key)?; },
}
- self.update_preview().ok();
+ self.update_preview()?;
Ok(())
}
}
diff --git a/src/files.rs b/src/files.rs
index 44863e6..fe0dc8b 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -2,17 +2,18 @@ use std::cmp::{Ord, Ordering};
use std::ops::Index;
use std::os::unix::fs::MetadataExt;
use std::path::{Path, PathBuf};
+use std::sync::{Arc, Mutex};
use lscolors::LsColors;
use mime_detective;
use users;
use chrono::TimeZone;
use failure::Error;
-use notify::{INotifyWatcher, Watcher, DebouncedEvent, RecursiveMode};
+use notify::DebouncedEvent;
use crate::fail::{HResult, HError};
-use std::sync::{Arc, Mutex};
+
lazy_static! {
@@ -200,7 +201,7 @@ impl Files {
DebouncedEvent::Write(path) | DebouncedEvent::Chmod(path) => {
self.path_in_here(&path)?;
let file = self.find_file_with_path(&path)?;
- file.reload_meta();
+ file.reload_meta()?;
},
DebouncedEvent::Remove(path) => {
self.path_in_here(&path)?;
diff --git a/src/hbox.rs b/src/hbox.rs
index 7e27656..6a2aa8e 100644
--- a/src/hbox.rs
+++ b/src/hbox.rs
@@ -1,20 +1,20 @@
use termion::event::{Event};
-use crate::widget::Widget;
+use crate::widget::{Widget, WidgetCore};
use crate::coordinates::{Coordinates, Size, Position};
-use crate::fail::HResult;
+use crate::fail::{HResult, ErrorLog};
#[derive(PartialEq)]
pub struct HBox<T: Widget> {
- pub coordinates: Coordinates,
+ pub core: WidgetCore,
pub widgets: Vec<T>,
pub active: Option<usize>,
}
impl<T> HBox<T> where T: Widget + PartialEq {
- pub fn new() -> HBox<T> {
- HBox { coordinates: Coordinates::new(),
+ pub fn new(core: &WidgetCore) -> HBox<T> {
+ HBox { core: core.clone(),
widgets: vec![],
active: None
}
@@ -27,34 +27,35 @@ impl<T> HBox<T> where T: Widget + PartialEq {
|w|
self.calculate_coordinates(w)).collect();
for (widget, coord) in self.widgets.iter_mut().zip(coords.iter()) {
- widget.set_coordinates(coord);
+ widget.set_coordinates(coord).log();
}
}
pub fn push_widget(&mut self, widget: T) where T: PartialEq {
self.widgets.push(widget);
self.resize_children();
- self.refresh();
+ self.refresh().log();
}
pub fn pop_widget(&mut self) -> Option<T> {
let widget = self.widgets.pop();
self.resize_children();
- self.refresh();
+ self.refresh().log();
widget
}
pub fn prepend_widget(&mut self, widget: T) {
self.widgets.insert(0, widget);
self.resize_children();
- self.refresh();
+ self.refresh().log();
}
- pub fn calculate_coordinates(&self, widget: &T)
+ pub fn calculate_coordinates(&self, widget: &T)
-> Coordinates where T: PartialEq {
- let xsize = self.coordinates.xsize();
- let ysize = self.coordinates.ysize();
- let top = self.coordinates.top().y();
+ let coordinates = self.get_coordinates().unwrap();
+ let xsize = coordinates.xsize();
+ let ysize = coordinates.ysize();
+ let top = coordinates.top().y();
let pos = self.widgets.iter().position(|w | w == widget).unwrap();
let num = self.widgets.len();
@@ -69,7 +70,7 @@ impl<T> HBox<T> where T: Widget + PartialEq {
top))
}
}
-
+
pub fn active_widget(&self) -> &T {
&self.widgets.last().unwrap()
}
@@ -80,35 +81,32 @@ impl<T> HBox<T> where T: Widget + PartialEq {
impl<T> Widget for HBox<T> where T: Widget + PartialEq {
- fn render_header(&self) -> String {
+ fn get_core(&self) -> HResult<&WidgetCore> {
+ Ok(&self.core)
+ }
+ fn get_core_mut(&mut self) -> HResult<&mut WidgetCore> {
+ Ok(&mut self.core)
+ }
+ fn render_header(&self) -> HResult<String> {
self.active_widget().render_header()
}
- fn refresh(&mut self) {
+ fn refresh(&mut self) -> HResult<()> {
self.resize_children();
for child in &mut self.widgets {
- child.refresh();
+ child.refresh()?
}
+ Ok(())
}
- fn get_drawlist(&self) -> String {
- self.widgets.iter().map(|child| {
- child.get_drawlist()
- }).collect()
+ fn get_drawlist(&self) -> HResult<String> {
+ Ok(self.widgets.iter().map(|child| {
+ child.get_drawlist().unwrap()
+ }).collect())
}
- fn get_coordinates(&self) -> &Coordinates {
- &self.coordinates
- }
- fn set_coordinates(&mut self, coordinates: &Coordinates) {
- if self.coordinates == *coordinates {
- return;
- }
- self.coordinates = coordinates.clone();
- self.refresh();
- }
fn on_event(&mut self, event: Event) -> HResult<()> {
- self.widgets.last_mut()?.on_event(event).ok();
+ self.widgets.last_mut()?.on_event(event)?;
Ok(())
}
}
diff --git a/src/listview.rs b/src/listview.rs
index 0a25dca..64ec5ac 100644
--- a/src/listview.rs
+++ b/src/listview.rs
@@ -3,17 +3,16 @@ use unicode_width::UnicodeWidthStr;
use std::path::{Path, PathBuf};
-use crate::coordinates::{Coordinates, Position, Size};
use crate::files::{File, Files};
-use crate::fail::HResult;
+use crate::fail::{HResult, ErrorLog};
use crate::term;
-use crate::widget::{Widget};
+use crate::widget::{Widget, WidgetCore};
pub trait Listable {
fn len(&self) -> usize;
fn render(&self) -> Vec<String>;
- fn on_refresh(&mut self) {}
- fn on_key(&mut self, _key: Key) {}
+ fn on_refresh(&mut self) -> HResult<()> { Ok(()) }
+ fn on_key(&mut self, _key: Key) -> HResult<()> { Ok(()) }
}
impl Listable for ListView<Files> {
@@ -25,26 +24,27 @@ impl Listable for ListView<Files> {
self.render()
}
- fn on_refresh(&mut self) {
- let visible_file_num = self.selection + self.get_coordinates().ysize() as usize;
+ fn on_refresh(&mut self) -> HResult<()> {
+ let visible_file_num = self.selection + self.get_coordinates()?.ysize() as usize;
self.content.meta_upto(visible_file_num);
+ Ok(())
}
- fn on_key(&mut self, key: Key) {
+ fn on_key(&mut self, key: Key) -> HResult<()> {
match key {
Key::Up | Key::Char('p') => {
self.move_up();
- self.refresh();
+ self.refresh()?;
}
- Key::Char('P') => { for _ in 0..10 { self.move_up() } self.refresh(); }
- Key::Char('N') => { for _ in 0..10 { self.move_down() } self.refresh(); }
+ Key::Char('P') => { for _ in 0..10 { self.move_up() } self.refresh()?; }
+ Key::Char('N') => { for _ in 0..10 { self.move_down() } self.refresh()?; }
Key::Down | Key::Char('n') => {
self.move_down();
- self.refresh();
+ self.refresh()?;
},
Key::Ctrl('s') => { self.find_file().ok(); }
- Key::Left => self.goto_grand_parent(),
- Key::Right => self.goto_selected(),
+ Key::Left => self.goto_grand_parent()?,
+ Key::Right => self.goto_selected()?,
Key::Char(' ') => self.multi_select_file(),
Key::Char('h') => self.toggle_hidden(),
Key::Char('r') => self.reverse_sort(),
@@ -52,8 +52,9 @@ impl Listable for ListView<Files> {
Key::Char('K') => self.select_next_mtime(),
Key::Char('k') => self.select_prev_mtime(),
Key::Char('d') => self.toggle_dirs_first(),
- _ => self.bad(Event::Key(key))
+ _ => { self.bad(Event::Key(key))?; }
}
+ Ok(())
}
}
@@ -65,7 +66,7 @@ pub struct ListView<T> where ListView<T>: Listable
selection: usize,
offset: usize,
buffer: Vec<String>,
- coordinates: Coordinates,
+ core: WidgetCore,
seeking: bool,
}
@@ -74,17 +75,14 @@ where
ListView<T>: Widget,
ListView<T>: Listable
{
- pub fn new(content: T) -> ListView<T> {
+ pub fn new(core: &WidgetCore, content: T) -> ListView<T> {
let view = ListView::<T> {
content: content,
lines: 0,
selection: 0,
offset: 0,
buffer: Vec::new(),
- coordinates: Coordinates {
- size: Size((1, 1)),
- position: Position((1, 1)),
- },
+ core: core.clone(),
seeking: false
};
view
@@ -104,7 +102,7 @@ where
}
pub fn move_down(&mut self) {
let lines = self.lines;
- let y_size = self.coordinates.ysize() as usize;
+ let y_size = self.get_coordinates().unwrap().ysize() as usize;
if self.lines == 0 || self.selection == lines - 1 {
return;
@@ -123,7 +121,7 @@ where
}
fn set_selection(&mut self, position: usize) {
- let ysize = self.coordinates.ysize() as usize;
+ let ysize = self.get_coordinates().unwrap().ysize() as usize;
let mut offset = 0;
while position + 2
@@ -145,7 +143,7 @@ where
} else { (name.clone(), "".to_string()) };
- let xsize = self.get_coordinates().xsize();
+ let xsize = self.get_coordinates().unwrap().xsize();
let sized_string = term::sized_string(&name, xsize);
let size_pos = xsize - (size.to_string().len() as u16
+ unit.to_string().len() as u16);
@@ -202,30 +200,29 @@ impl ListView<Files>
self.selected_file().grand_parent()
}
- pub fn goto_grand_parent(&mut self) {
+ pub fn goto_grand_parent(&mut self) -> HResult<()> {
match self.grand_parent() {
Some(grand_parent) => self.goto_path(&grand_parent),
- None => self.show_status("Can't go further!"),
+ None => { self.show_status("Can't go further!") },
}
}
- fn goto_selected(&mut self) {
+ fn goto_selected(&mut self) -> HResult<()> {
let path = self.selected_file().path();
- self.goto_path(&path);
+ self.goto_path(&path)
}
- pub fn goto_path(&mut self, 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();
+ self.refresh()
}
Err(err) => {
- self.show_status(&format!("Can't open this path: {}", err));
- return;
+ self.show_status(&format!("Can't open this path: {}", err))
}
}
}
@@ -245,8 +242,8 @@ impl ListView<Files>
self.content.cycle_sort();
self.content.sort();
self.select_file(&file);
- self.refresh();
- self.show_status(&format!("Sorting by: {}", self.content.sort));
+ self.refresh().log();
+ self.show_status(&format!("Sorting by: {}", self.content.sort)).log();
}
fn reverse_sort(&mut self) {
@@ -254,8 +251,8 @@ impl ListView<Files>
self.content.reverse_sort();
self.content.sort();
self.select_file(&file);
- self.refresh();
- self.show_status(&format!("Reversed sorting by: {}", self.content.sort));
+ self.refresh().log();
+ self.show_status(&format!("Reversed sorting by: {}", self.content.sort)).log();
}
fn select_next_mtime(&mut self) {
@@ -283,7 +280,7 @@ impl ListView<Files>
self.select_file(&file);
self.seeking = true;
- self.refresh();
+ self.refresh().log();
}
fn select_prev_mtime(&mut self) {
@@ -310,7 +307,7 @@ impl ListView<Files>
self.select_file(&file);
self.seeking = true;
- self.refresh();
+ self.refresh().log();
}
fn toggle_hidden(&mut self) {
@@ -318,7 +315,7 @@ impl ListView<Files>
self.content.toggle_hidden();
self.content.reload_files();
self.select_file(&file);
- self.refresh();
+ self.refresh().log();
}
fn toggle_dirs_first(&mut self) {
@@ -326,15 +323,16 @@ impl ListView<Files>
self.content.dirs_first = !self.content.dirs_first;
self.content.sort();
self.select_file(&file);
- self.refresh();
- self.show_status(&format!("Direcories first: {}", self.content.dirs_first));
+ self.refresh().log();
+ self.show_status(&format!("Direcories first: {}",
+ self.content.dirs_first)).log();
}
fn multi_select_file(&mut self) {
let file = self.selected_file_mut();
file.toggle_selection();
self.move_down();
- self.refresh();
+ self.refresh().log();
}
fn find_file(&mut self) -> HResult<()> {
@@ -352,7 +350,7 @@ impl ListView<Files>
}
fn render(&self) -> Vec<String> {
- let ysize = self.get_coordinates().ysize() as usize;
+ let ysize = self.get_coordinates().unwrap().ysize() as usize;
let offset = self.offset;
self.content
.files
@@ -366,29 +364,26 @@ impl ListView<Files>
impl<T> Widget for ListView<T> where ListView<T>: Listable {
- fn get_coordinates(&self) -> &Coordinates {
- &self.coordinates
+ fn get_core(&self) -> HResult<&WidgetCore> {
+ Ok(&self.core)
}
- fn set_coordinates(&mut self, coordinates: &Coordinates) {
- if self.coordinates == *coordinates {
- return;
- }
- self.coordinates = coordinates.clone();
- self.refresh();
+ fn get_core_mut(&mut self) -> HResult<&mut WidgetCore> {
+ Ok(&mut self.core)
}
- fn refresh(&mut self) {
- self.on_refresh();
+ fn refresh(&mut self) -> HResult<()> {
+ self.on_refresh().log();
self.lines = self.len();
if self.selection >= self.lines && self.selection != 0 {
self.selection -= 1;
}
self.buffer = self.render();
+ Ok(())
}
- fn get_drawlist(&self) -> String {
+ fn get_drawlist(&self) -> HResult<String> {
let mut output = term::reset();
- let (xpos, ypos) = self.coordinates.position().position();
+ let (xpos, ypos) = self.get_coordinates().unwrap().position().position();
output += &self
.buffer
@@ -410,16 +405,15 @@ impl<T> Widget for ListView<T> where ListView<T>: Listable {
})
.collect::<String>();