summaryrefslogtreecommitdiffstats
path: root/src/fs/dirlist.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/dirlist.rs')
-rw-r--r--src/fs/dirlist.rs62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/fs/dirlist.rs b/src/fs/dirlist.rs
index 096c9a0..567b8eb 100644
--- a/src/fs/dirlist.rs
+++ b/src/fs/dirlist.rs
@@ -15,6 +15,8 @@ pub struct JoshutoDirList {
index: Option<usize>,
/// The index in this dir list to start with when rendering the list
viewport_index: usize,
+ /// The index in this dir list where visual mode has started or None if not in visual mode
+ visual_mode_anchor_index: Option<usize>,
_need_update: bool,
}
@@ -24,6 +26,7 @@ impl JoshutoDirList {
contents: Vec<JoshutoDirEntry>,
index: Option<usize>,
viewport_index: usize,
+ visual_mode_anchor_index: Option<usize>,
metadata: JoshutoMetadata,
) -> Self {
Self {
@@ -32,6 +35,7 @@ impl JoshutoDirList {
metadata,
index,
viewport_index,
+ visual_mode_anchor_index,
_need_update: false,
}
}
@@ -55,6 +59,7 @@ impl JoshutoDirList {
_need_update: false,
index,
viewport_index: if let Some(ix) = index { ix } else { 0 },
+ visual_mode_anchor_index: None,
})
}
@@ -62,6 +67,62 @@ impl JoshutoDirList {
self.index
}
+ pub fn get_visual_mode_anchor_index(&self) -> Option<usize> {
+ self.visual_mode_anchor_index
+ }
+
+ fn update_visual_mode_selection(&mut self) {
+ //! To be invoked any time the cursor index, the visual mode anchor index,
+ //! or the shown sub-set of entries changes.
+ if let Some(vmix) = self.visual_mode_anchor_index {
+ if let Some(cix) = self.index {
+ self.iter_mut().enumerate().for_each(|(i, entry)| {
+ entry.set_visual_mode_selected(
+ (if vmix > cix {
+ cix..vmix + 1
+ } else {
+ vmix..cix + 1
+ })
+ .contains(&i),
+ )
+ })
+ }
+ } else {
+ self.iter_mut()
+ .for_each(|entry| entry.set_visual_mode_selected(false))
+ }
+ }
+
+ fn visual_mode_enable(&mut self) {
+ if let Some(ix) = self.index {
+ self.visual_mode_anchor_index = Some(ix)
+ };
+ self.update_visual_mode_selection();
+ }
+
+ fn visual_mode_disable(&mut self) {
+ self.visual_mode_anchor_index = None;
+ self.iter_mut().for_each(|entry| {
+ if entry.is_visual_mode_selected() {
+ entry.set_permanent_selected(true)
+ }
+ });
+ self.update_visual_mode_selection();
+ }
+
+ pub fn visual_mode_cancel(&mut self) {
+ self.visual_mode_anchor_index = None;
+ self.update_visual_mode_selection();
+ }
+
+ pub fn toggle_visual_mode(&mut self) {
+ if self.get_visual_mode_anchor_index().is_none() {
+ self.visual_mode_enable()
+ } else {
+ self.visual_mode_disable()
+ }
+ }
+
fn update_viewport(&mut self, ui_context: &UiContext, options: &DisplayOption) {
if let Some(ix) = self.index {
let height = ui_context.layout[0].height as usize;
@@ -106,6 +167,7 @@ impl JoshutoDirList {
if !ui_context.layout.is_empty() {
self.update_viewport(ui_context, options);
}
+ self.update_visual_mode_selection();
}
pub fn iter(&self) -> Iter<JoshutoDirEntry> {