summaryrefslogtreecommitdiffstats
path: root/src/listview.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/listview.rs')
-rw-r--r--src/listview.rs66
1 files changed, 57 insertions, 9 deletions
diff --git a/src/listview.rs b/src/listview.rs
index be27dd8..d048b4f 100644
--- a/src/listview.rs
+++ b/src/listview.rs
@@ -1,3 +1,4 @@
+use std::fmt::Debug;
use termion::event::Key;
use unicode_width::UnicodeWidthStr;
@@ -10,6 +11,7 @@ use crate::widget::{Widget, WidgetCore};
use crate::dirty::Dirtyable;
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()) }
@@ -32,6 +34,8 @@ impl Acting for ListView<Files> {
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()?; }
@@ -42,12 +46,18 @@ impl Acting for ListView<Files> {
Left | Right => {}
}
+ if pos != self.get_selection() {
+ self.update_selected_file();
+ }
+
Ok(())
}
fn do_action(&mut self, action: &Self::Action) -> HResult<()> {
use FileListAction::*;
+ let pos = self.get_selection();
+
match action {
Search => self.search_file()?,
SearchNext => self.search_next()?,
@@ -65,11 +75,18 @@ impl Acting for ListView<Files> {
ToPrevMtime => self.select_prev_mtime(),
ToggleDirsFirst => self.toggle_dirs_first(),
}
+
+ if pos != self.get_selection() {
+ self.update_selected_file();
+ }
+
Ok(())
}
}
impl Listable for ListView<Files> {
+ type Item = File;
+
fn len(&self) -> usize {
self.content.len()
}
@@ -81,6 +98,12 @@ 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 file = self.content
+ .iter_files()
+ .nth(0)
+ .cloned()
+ .unwrap_or_default();
+ self.current_item = Some(file);
Ok(())
}
@@ -117,9 +140,12 @@ impl Listable for ListView<Files> {
}
#[derive(Debug, PartialEq)]
-pub struct ListView<T> where ListView<T>: Listable
+pub struct ListView<T>
+where
+ ListView<T>: Listable
{
pub content: T,
+ pub current_item: Option<<ListView<T> as Listable>::Item>,
pub lines: usize,
selection: usize,
pub offset: usize,
@@ -137,6 +163,7 @@ where
pub fn new(core: &WidgetCore, content: T) -> ListView<T> {
let mut view = ListView::<T> {
content: content,
+ current_item: None,
lines: 0,
selection: 0,
offset: 0,
@@ -222,13 +249,19 @@ where
impl ListView<Files>
{
- pub fn selected_file(&self) -> &File {
- let selection = self.selection;
+ pub fn update_selected_file(&mut self) {
+ let pos = self.selection;
- &self.content
+ let file = self.content
.iter_files()
- .nth(selection)
- .unwrap_or(&self.content.directory)
+ .nth(pos)
+ .map(|f| f.clone());
+
+ self.current_item = file;
+ }
+
+ pub fn selected_file(&self) -> &File {
+ self.current_item.as_ref().unwrap()
}
pub fn selected_file_mut(&mut self) -> &mut File {
@@ -288,6 +321,8 @@ impl ListView<Files>
}
pub fn select_file(&mut self, file: &File) {
+ self.current_item = Some(file.clone());
+
let pos = self
.content
.iter_files()
@@ -375,6 +410,8 @@ impl ListView<Files>
self.content.toggle_hidden();
self.select_file(&file);
self.refresh().log();
+ self.core.show_status(&format!("Showing hidden files: {}",
+ self.content.show_hidden)).log();
}
fn toggle_dirs_first(&mut self) {
@@ -390,9 +427,13 @@ impl ListView<Files>
fn multi_select_file(&mut self) {
self.selected_file_mut().toggle_selection();
+ // Create mutable clone to render change
+ let mut file = self.clone_selected_file();
+ file.toggle_selection();
+
if !self.content.filter_selected {
let selection = self.get_selection();
- let line = self.render_line(self.selected_file());
+ let line = self.render_line(&file);
self.buffer[selection] = line;
self.move_down();
@@ -432,8 +473,12 @@ 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();
- let line = self.render_line(self.selected_file());
self.buffer[selection] = line;
self.move_down();
@@ -689,7 +734,10 @@ impl ListView<Files>
}
-impl<T> Widget for ListView<T> where ListView<T>: Listable {
+impl<T> Widget for ListView<T>
+where
+ ListView<T>: Listable
+{
fn get_core(&self) -> HResult<&WidgetCore> {
Ok(&self.core)
}