summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/event_dispatch.rs6
-rw-r--r--src/event_exec.rs14
-rw-r--r--src/fileinfo.rs26
-rw-r--r--src/indexed_vector.rs45
-rw-r--r--src/lib.rs2
-rw-r--r--src/selectable_content.rs66
-rw-r--r--src/shortcut.rs4
-rw-r--r--src/tab.rs2
-rw-r--r--src/term_manager.rs2
-rw-r--r--src/visited.rs4
10 files changed, 110 insertions, 61 deletions
diff --git a/src/event_dispatch.rs b/src/event_dispatch.rs
index 3e5ab28..bc773ba 100644
--- a/src/event_dispatch.rs
+++ b/src/event_dispatch.rs
@@ -79,9 +79,9 @@ impl EventDispatcher {
Some(event_char) => event_char.matcher(status),
None => Ok(()),
},
- Mode::Preview | Mode::Shortcut => EventExec::event_normal(status.selected()),
- Mode::Jump => Ok(()),
- Mode::History => Ok(()),
+ Mode::Preview | Mode::Shortcut | Mode::Jump | Mode::History => {
+ EventExec::event_normal(status.selected())
+ }
Mode::NeedConfirmation(confirmed_action) => {
if c == 'y' {
let _ = EventExec::exec_confirmed_action(status, confirmed_action);
diff --git a/src/event_exec.rs b/src/event_exec.rs
index a2219f8..be9d2d3 100644
--- a/src/event_exec.rs
+++ b/src/event_exec.rs
@@ -13,10 +13,10 @@ use crate::copy_move::CopyMove;
use crate::fileinfo::{FileKind, PathContent};
use crate::filter::FilterKind;
use crate::fm_error::{FmError, FmResult};
-use crate::indexed_vector::IndexedVector;
use crate::mode::{ConfirmedAction, InputKind, MarkAction, Mode};
use crate::opener::execute_in_child;
use crate::preview::Preview;
+use crate::selectable_content::SelectableContent;
use crate::status::Status;
use crate::tab::Tab;
use crate::term_manager::MIN_WIDTH_FOR_DUAL_PANE;
@@ -308,7 +308,9 @@ impl EventExec {
pub fn event_up_one_row(tab: &mut Tab) {
match tab.mode {
Mode::Normal => {
+ tab.path_content.unselect_current();
tab.path_content.prev();
+ tab.path_content.select_current();
tab.move_line_up();
}
Mode::Preview => tab.line_index = tab.window.top,
@@ -321,7 +323,9 @@ impl EventExec {
pub fn event_down_one_row(tab: &mut Tab) {
match tab.mode {
Mode::Normal => {
+ tab.path_content.unselect_current();
tab.path_content.next();
+ tab.path_content.select_current();
tab.move_line_down();
}
Mode::Preview => tab.line_index = tab.window.bottom,
@@ -420,13 +424,17 @@ impl EventExec {
}
/// Select the next element in history of visited files.
+ /// Watchout! Since the history is displayed in reverse order,
+ /// we call the "prev" method of the `History` instance instead.
pub fn event_history_next(tab: &mut Tab) {
- tab.history.next()
+ tab.history.prev()
}
/// Select the previous element in history of visited files.
+ /// Watchout! Since the history is displayed in reverse order,
+ /// we call the "next" method of the `History` instance instead.
pub fn event_history_prev(tab: &mut Tab) {
- tab.history.prev()
+ tab.history.next()
}
/// Move to parent directory if there's one.
diff --git a/src/fileinfo.rs b/src/fileinfo.rs
index 27e7798..fe44ad3 100644
--- a/src/fileinfo.rs
+++ b/src/fileinfo.rs
@@ -13,7 +13,7 @@ use crate::constant_strings_paths::PERMISSIONS_STR;
use crate::filter::FilterKind;
use crate::fm_error::{FmError, FmResult};
use crate::git::git;
-use crate::impl_indexed_vector;
+use crate::impl_selectable_content;
use crate::sort::SortKind;
use crate::status::Status;
@@ -410,13 +410,33 @@ impl PathContent {
Ok(git(&self.path)?)
}
- /// Update the kind of sort
+ /// Update the kind of sort from a char typed by the user.
pub fn update_sort_from_char(&mut self, c: char) {
self.sort_kind.update_from_char(c)
}
+
+ /// Unselect the current item.
+ /// Since we use a common trait to navigate the files,
+ /// this method is required.
+ pub fn unselect_current(&mut self) {
+ if self.is_empty() {
+ return;
+ }
+ self.content[self.index].unselect();
+ }
+
+ /// Select the current item.
+ /// Since we use a common trait to navigate the files,
+ /// this method is required.
+ pub fn select_current(&mut self) {
+ if self.is_empty() {
+ return;
+ }
+ self.content[self.index].select();
+ }
}
-impl_indexed_vector!(FileInfo, PathContent);
+impl_selectable_content!(FileInfo, PathContent);
/// Associates a filetype to `tuikit::prelude::Attr` : fg color, bg color and
/// effect.
diff --git a/src/indexed_vector.rs b/src/indexed_vector.rs
deleted file mode 100644
index 050e95a..0000000
--- a/src/indexed_vector.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-pub trait IndexedVector<T> {
- fn is_empty(&self) -> bool;
- fn len(&self) -> usize;
- fn next(&mut self);
- fn prev(&mut self);
- fn selected(&self) -> Option<&T>;
-}
-
-#[macro_export]
-macro_rules! impl_indexed_vector {
- ($t:ident, $u:ident) => {
- use crate::indexed_vector::IndexedVector;
-
- impl IndexedVector<$t> for $u {
- fn is_empty(&self) -> bool {
- self.content.is_empty()
- }
-
- fn len(&self) -> usize {
- self.content.len()
- }
-
- fn next(&mut self) {
- if self.is_empty() {
- self.index = 0
- } else if self.index > 0 {
- self.index -= 1;
- } else {
- self.index = self.len() - 1
- }
- }
-
- fn prev(&mut self) {
- if self.is_empty() {
- self.index = 0;
- } else {
- self.index = (self.index + 1) % self.len()
- }
- }
- fn selected(&self) -> Option<&$t> {
- Some(&self.content[self.index])
- }
- }
- };
-}
diff --git a/src/lib.rs b/src/lib.rs
index a4d9a73..c4bf51a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -15,7 +15,6 @@ pub mod filter;
pub mod fm_error;
pub mod git;
pub mod help;
-pub mod indexed_vector;
pub mod input;
pub mod keybindings;
pub mod log;
@@ -23,6 +22,7 @@ pub mod marks;
pub mod mode;
pub mod opener;
pub mod preview;
+pub mod selectable_content;
pub mod shortcut;
pub mod skim;
pub mod sort;
diff --git a/src/selectable_content.rs b/src/selectable_content.rs
new file mode 100644
index 0000000..4669e70
--- /dev/null
+++ b/src/selectable_content.rs
@@ -0,0 +1,66 @@
+/// Make a content selectable content for a struct.
+/// This trait allows to navigate through a vector of element `content_type`.
+/// It implements: `is_empty`, `len`, `next`, `prev`, `selected`.
+/// `selected` returns an optional reference to the value.
+pub trait SelectableContent<T> {
+ fn is_empty(&self) -> bool;
+ fn len(&self) -> usize;
+ fn next(&mut self);
+ fn prev(&mut self);
+ fn selected(&self) -> Option<&T>;
+}
+
+/// Implement the `SelectableContent` for struct `$struc` with content type `$content_type`.
+/// This trait allows to navigate through a vector of element `content_type`.
+/// It implements: `is_empty`, `len`, `next`, `prev`, `selected`.
+/// `selected` returns an optional reference to the value.
+#[macro_export]
+macro_rules! impl_selectable_content {
+ ($content_type:ident, $struct:ident) => {
+ use $crate::selectable_content::SelectableContent;
+
+ /// Implement a selectable content for this struct.
+ /// This trait allows to navigate through a vector of element `content_type`.
+ /// It implements: `is_empty`, `len`, `next`, `prev`, `selected`.
+ /// `selected` returns an optional reference to the value.
+ impl SelectableContent<$content_type> for $struct {
+ /// True if the content is empty.
+ fn is_empty(&self) -> bool {
+ self.content.is_empty()
+ }
+
+ /// The size of the content.
+ fn len(&self) -> usize {
+ self.content.len()
+ }
+
+ /// Select the prev item.
+ fn prev(&mut self) {
+ if self.is_empty() {
+ self.index = 0
+ } else if self.index > 0 {
+ self.index -= 1;
+ } else {
+ self.index = self.len() - 1
+ }
+ }
+
+ /// Select the next item.
+ fn next(&mut self) {
+ if self.is_empty() {
+ self.index = 0;
+ } else {
+ self.index = (self.index + 1) % self.len()
+ }
+ }
+
+ /// Returns a reference to the selected content.
+ fn selected(&self) -> Option<&$content_type> {
+ match self.is_empty() {
+ true => None,
+ false => Some(&self.content[self.index]),
+ }
+ }
+ }
+ };
+}
diff --git a/src/shortcut.rs b/src/shortcut.rs
index 7ecf89c..98f0b8e 100644
--- a/src/shortcut.rs
+++ b/src/shortcut.rs
@@ -3,7 +3,7 @@ use std::path::{Path, PathBuf};
use std::str::FromStr;
use crate::constant_strings_paths::HARDCODED_SHORTCUTS;
-use crate::impl_indexed_vector;
+use crate::impl_selectable_content;
/// Holds the hardcoded and mountpoints shortcuts the user can jump to.
/// Also know which shortcut is currently selected by the user.
@@ -62,4 +62,4 @@ impl Shortcut {
}
}
-impl_indexed_vector!(PathBuf, Shortcut);
+impl_selectable_content!(PathBuf, Shortcut);
diff --git a/src/tab.rs b/src/tab.rs
index 32fddea..e9dce5a 100644
--- a/src/tab.rs
+++ b/src/tab.rs
@@ -6,10 +6,10 @@ use crate::content_window::ContentWindow;
use crate::fileinfo::PathContent;
use crate::filter::FilterKind;
use crate::fm_error::{FmError, FmResult};
-use crate::indexed_vector::IndexedVector;
use crate::input::Input;
use crate::mode::Mode;
use crate::preview::Preview;
+use crate::selectable_content::SelectableContent;
use crate::shortcut::Shortcut;
use crate::visited::History;
diff --git a/src/term_manager.rs b/src/term_manager.rs
index d01a190..eea7c76 100644
--- a/src/term_manager.rs
+++ b/src/term_manager.rs
@@ -15,9 +15,9 @@ use crate::constant_strings_paths::{
use crate::content_window::ContentWindow;
use crate::fileinfo::fileinfo_attr;
use crate::fm_error::{FmError, FmResult};
-use crate::indexed_vector::IndexedVector;
use crate::mode::{ConfirmedAction, InputKind, MarkAction, Mode};
use crate::preview::{Preview, TextKind, Window};
+use crate::selectable_content::SelectableContent;
use crate::status::Status;
use crate::tab::Tab;
diff --git a/src/visited.rs b/src/visited.rs
index a01c28d..e51cb4c 100644
--- a/src/visited.rs
+++ b/src/visited.rs
@@ -1,6 +1,6 @@
use std::path::PathBuf;
-use crate::impl_indexed_vector;
+use crate::impl_selectable_content;
/// A Vec of pathbuf of visited files.
/// It's mostly used as a stack but we want to avoid multiple instances of the
@@ -41,4 +41,4 @@ impl History {
}
}
-impl_indexed_vector!(PathBuf, History);
+impl_selectable_content!(PathBuf, History);