summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/configuration/joshuto.toml.md1
-rw-r--r--src/commands/change_directory.rs3
-rw-r--r--src/commands/cursor_move.rs20
-rw-r--r--src/commands/parent_cursor_move.rs14
-rw-r--r--src/commands/search_glob.rs4
-rw-r--r--src/commands/search_string.rs4
-rw-r--r--src/commands/subdir_fzf.rs4
-rw-r--r--src/commands/tab_ops.rs6
-rw-r--r--src/context/app_context.rs16
-rw-r--r--src/fs/dirlist.rs82
-rw-r--r--src/history.rs40
-rw-r--r--src/preview/preview_default.rs2
-rw-r--r--src/run.rs60
-rw-r--r--src/tab.rs13
-rw-r--r--src/ui/widgets/tui_dirlist.rs33
-rw-r--r--src/ui/widgets/tui_dirlist_detailed.rs64
-rw-r--r--src/ui/widgets/tui_footer.rs2
-rw-r--r--src/util/input.rs3
18 files changed, 234 insertions, 137 deletions
diff --git a/docs/configuration/joshuto.toml.md b/docs/configuration/joshuto.toml.md
index eeacf58..a1171be 100644
--- a/docs/configuration/joshuto.toml.md
+++ b/docs/configuration/joshuto.toml.md
@@ -4,7 +4,6 @@ This file is for general configurations.
All options available and their default values:
```toml
# This is for configuring how many items to reach before 'scrolling' the view
-# CURRENTLY DOES NOT WORK
scroll_offset = 6
# If joshuto does not know how to open the file, it can resort to opening it via xdg settings
diff --git a/src/commands/change_directory.rs b/src/commands/change_directory.rs
index 7b89726..6a39337 100644
--- a/src/commands/change_directory.rs
+++ b/src/commands/change_directory.rs
@@ -13,11 +13,12 @@ pub fn cd(path: &path::Path, context: &mut AppContext) -> std::io::Result<()> {
fn change_directory_helper(path: &path::Path, context: &mut AppContext) -> std::io::Result<()> {
cd(path, context)?;
let options = context.config_ref().display_options_ref().clone();
+ let ui_context = context.ui_context_ref().clone();
context
.tab_context_mut()
.curr_tab_mut()
.history_mut()
- .populate_to_root(path, &options)?;
+ .populate_to_root(path, &ui_context, &options)?;
Ok(())
}
diff --git a/src/commands/cursor_move.rs b/src/commands/cursor_move.rs
index def90b2..5d9430f 100644
--- a/src/commands/cursor_move.rs
+++ b/src/commands/cursor_move.rs
@@ -41,20 +41,24 @@ pub fn lazy_load_directory_size(context: &mut AppContext) {
pub fn cursor_move(context: &mut AppContext, new_index: usize) {
lazy_load_directory_size(context);
let mut new_index = new_index;
+ let ui_context = context.ui_context_ref().clone();
+ let display_options = context.config_ref().display_options_ref().clone();
if let Some(curr_list) = context.tab_context_mut().curr_tab_mut().curr_list_mut() {
if !curr_list.is_empty() {
let dir_len = curr_list.len();
if new_index >= dir_len {
new_index = dir_len - 1;
}
- curr_list.index = Some(new_index);
+ curr_list.set_index(Some(new_index), &ui_context, &display_options);
}
}
}
pub fn up(context: &mut AppContext, u: usize) -> JoshutoResult<()> {
let movement = match context.tab_context_ref().curr_tab_ref().curr_list_ref() {
- Some(curr_list) => curr_list.index.map(|idx| if idx > u { idx - u } else { 0 }),
+ Some(curr_list) => curr_list
+ .get_index()
+ .map(|idx| if idx > u { idx - u } else { 0 }),
None => None,
};
@@ -66,7 +70,7 @@ pub fn up(context: &mut AppContext, u: usize) -> JoshutoResult<()> {
pub fn down(context: &mut AppContext, u: usize) -> JoshutoResult<()> {
let movement = match context.tab_context_ref().curr_tab_ref().curr_list_ref() {
- Some(curr_list) => curr_list.index.map(|idx| idx + u),
+ Some(curr_list) => curr_list.get_index().map(|idx| idx + u),
None => None,
};
if let Some(s) = movement {
@@ -135,9 +139,11 @@ pub fn page_up(context: &mut AppContext, backend: &mut TuiBackend) -> JoshutoRes
let page_size = get_page_size(context, backend).unwrap_or(10);
let movement = match context.tab_context_ref().curr_tab_ref().curr_list_ref() {
- Some(curr_list) => curr_list
- .index
- .map(|idx| if idx > page_size { idx - page_size } else { 0 }),
+ Some(curr_list) => {
+ curr_list
+ .get_index()
+ .map(|idx| if idx > page_size { idx - page_size } else { 0 })
+ }
None => None,
};
@@ -153,7 +159,7 @@ pub fn page_down(context: &mut AppContext, backend: &mut TuiBackend) -> JoshutoR
let movement = match context.tab_context_ref().curr_tab_ref().curr_list_ref() {
Some(curr_list) => {
let dir_len = curr_list.len();
- curr_list.index.map(|idx| {
+ curr_list.get_index().map(|idx| {
if idx + page_size > dir_len - 1 {
dir_len - 1
} else {
diff --git a/src/commands/parent_cursor_move.rs b/src/commands/parent_cursor_move.rs
index d1247d1..3bab3d3 100644
--- a/src/commands/parent_cursor_move.rs
+++ b/src/commands/parent_cursor_move.rs
@@ -8,17 +8,19 @@ pub fn parent_cursor_move(context: &mut AppContext, new_index: usize) -> Joshuto
let mut new_index = new_index;
{
+ let ui_context = context.ui_context_ref().clone();
+ let display_options = context.config_ref().display_options_ref().clone();
let curr_tab = context.tab_context_mut().curr_tab_mut();
if let Some(curr_list) = curr_tab.parent_list_mut() {
- if curr_list.index.is_some() {
+ if curr_list.get_index().is_some() {
let dir_len = curr_list.contents.len();
if new_index >= dir_len {
new_index = dir_len - 1;
}
let entry = &curr_list.contents[new_index];
if entry.file_path().is_dir() {
- curr_list.index = Some(new_index);
- path = Some(entry.file_path().to_path_buf())
+ path = Some(entry.file_path().to_path_buf());
+ curr_list.set_index(Some(new_index), &ui_context, &display_options);
}
}
}
@@ -31,7 +33,9 @@ pub fn parent_cursor_move(context: &mut AppContext, new_index: usize) -> Joshuto
pub fn parent_up(context: &mut AppContext, u: usize) -> JoshutoResult<()> {
let movement = match context.tab_context_ref().curr_tab_ref().parent_list_ref() {
- Some(list) => list.index.map(|idx| if idx > u { idx - u } else { 0 }),
+ Some(list) => list
+ .get_index()
+ .map(|idx| if idx > u { idx - u } else { 0 }),
None => None,
};
@@ -44,7 +48,7 @@ pub fn parent_up(context: &mut AppContext, u: usize) -> JoshutoResult<()> {
pub fn parent_down(context: &mut AppContext, u: usize) -> JoshutoResult<()> {
let movement = match context.tab_context_ref().curr_tab_ref().parent_list_ref() {
- Some(list) => list.index.map(|idx| idx + u),
+ Some(list) => list.get_index().map(|idx| idx + u),
None => None,
};
if let Some(s) = movement {
diff --git a/src/commands/search_glob.rs b/src/commands/search_glob.rs
index a6ca267..c761523 100644
--- a/src/commands/search_glob.rs
+++ b/src/commands/search_glob.rs
@@ -10,7 +10,7 @@ use super::cursor_move;
pub fn search_glob_fwd(curr_tab: &JoshutoTab, glob: &GlobMatcher) -> Option<usize> {
let curr_list = curr_tab.curr_list_ref()?;
- let offset = curr_list.index? + 1;
+ let offset = curr_list.get_index()? + 1;
let contents_len = curr_list.len();
for i in 0..contents_len {
let file_name = curr_list.contents[(offset + i) % contents_len].file_name();
@@ -23,7 +23,7 @@ pub fn search_glob_fwd(curr_tab: &JoshutoTab, glob: &GlobMatcher) -> Option<usiz
pub fn search_glob_rev(curr_tab: &JoshutoTab, glob: &GlobMatcher) -> Option<usize> {
let curr_list = curr_tab.curr_list_ref()?;
- let offset = curr_list.index?;
+ let offset = curr_list.get_index()?;
let contents_len = curr_list.len();
for i in (0..contents_len).rev() {
let file_name = curr_list.contents[(offset + i) % contents_len].file_name();
diff --git a/src/commands/search_string.rs b/src/commands/search_string.rs
index b5ea94a..62d9a7f 100644
--- a/src/commands/search_string.rs
+++ b/src/commands/search_string.rs
@@ -8,7 +8,7 @@ use super::cursor_move;
pub fn search_string_fwd(curr_tab: &JoshutoTab, pattern: &str) -> Option<usize> {
let curr_list = curr_tab.curr_list_ref()?;
- let offset = curr_list.index? + 1;
+ let offset = curr_list.get_index()? + 1;
let contents_len = curr_list.contents.len();
for i in 0..contents_len {
let file_name_lower = curr_list.contents[(offset + i) % contents_len]
@@ -23,7 +23,7 @@ pub fn search_string_fwd(curr_tab: &JoshutoTab, pattern: &str) -> Option<usize>
pub fn search_string_rev(curr_tab: &JoshutoTab, pattern: &str) -> Option<usize> {
let curr_list = curr_tab.curr_list_ref()?;
- let offset = curr_list.index?;
+ let offset = curr_list.get_index()?;
let contents_len = curr_list.contents.len();
for i in (0..contents_len).rev() {
let file_name_lower = curr_list.contents[(offset + i) % contents_len]
diff --git a/src/commands/subdir_fzf.rs b/src/commands/subdir_fzf.rs
index 74c86f2..51de88f 100644
--- a/src/commands/subdir_fzf.rs
+++ b/src/commands/subdir_fzf.rs
@@ -80,8 +80,10 @@ pub fn fzf_change_dir(context: &mut AppContext, path: &Path) -> JoshutoResult<()
};
if let Some(index) = index {
+ let ui_context = context.ui_context_ref().clone();
+ let display_options = context.config_ref().display_options_ref().clone();
if let Some(curr_list) = context.tab_context_mut().curr_tab_mut().curr_list_mut() {
- curr_list.index = Some(index);
+ curr_list.set_index(Some(index), &ui_context, &display_options);
}
}
}
diff --git a/src/commands/tab_ops.rs b/src/commands/tab_ops.rs
index 0d6ff82..dd27998 100644
--- a/src/commands/tab_ops.rs
+++ b/src/commands/tab_ops.rs
@@ -96,7 +96,11 @@ pub fn new_tab_home_path(context: &AppContext) -> path::PathBuf {
pub fn new_tab(context: &mut AppContext) -> JoshutoResult<()> {
let new_tab_path = new_tab_home_path(context);
- let tab = JoshutoTab::new(new_tab_path, context.config_ref().display_options_ref())?;
+ let tab = JoshutoTab::new(
+ new_tab_path,
+ context.ui_context_ref(),
+ context.config_ref().display_options_ref(),
+ )?;
context.tab_context_mut().push_tab(tab);
let new_index = context.tab_context_ref().len() - 1;
context.tab_context_mut().index = new_index;
diff --git a/src/context/app_context.rs b/src/context/app_context.rs
index 30aafae..0bdcf28 100644
--- a/src/context/app_context.rs
+++ b/src/context/app_context.rs
@@ -1,5 +1,6 @@
use std::collections::HashSet;
use std::sync::mpsc;
+use tui::layout::Rect;
use crate::config;
use crate::context::{
@@ -20,6 +21,11 @@ pub enum QuitType {
ChooseFiles,
}
+#[derive(Clone, Debug, PartialEq)]
+pub struct UiContext {
+ pub layout: Vec<Rect>,
+}
+
pub struct AppContext {
pub quit: QuitType,
// event loop querying
@@ -42,6 +48,8 @@ pub struct AppContext {
preview_context: PreviewContext,
// context related to command line
commandline_context: CommandLineContext,
+ // user interface context; data which is input to both, the UI rendering and the app state
+ ui_context: UiContext,
// filesystem watcher to inform about changes in shown directories
#[cfg(target_os = "linux")]
watcher: notify::INotifyWatcher,
@@ -81,6 +89,7 @@ impl AppContext {
message_queue: MessageQueue::new(),
worker_context: WorkerContext::new(event_tx),
preview_context: PreviewContext::new(),
+ ui_context: UiContext { layout: vec![] },
commandline_context,
config,
watcher,
@@ -172,6 +181,13 @@ impl AppContext {
&mut self.preview_context
}
+ pub fn ui_context_ref(&self) -> &UiContext {
+ &self.ui_context
+ }
+ pub fn ui_context_mut(&mut self) -> &mut UiContext {
+ &mut self.ui_context
+ }
+
pub fn worker_context_ref(&self) -> &WorkerContext {
&self.worker_context
}
diff --git a/src/fs/dirlist.rs b/src/fs/dirlist.rs
index 0c8d6d6..a2d4bb8 100644
--- a/src/fs/dirlist.rs
+++ b/src/fs/dirlist.rs
@@ -1,7 +1,9 @@
+use std::cmp;
use std::path;
use std::slice::{Iter, IterMut};
use crate::config::option::DisplayOption;
+use crate::context::UiContext;
use crate::fs::{JoshutoDirEntry, JoshutoMetadata};
use crate::history::read_directory;
@@ -10,8 +12,10 @@ pub struct JoshutoDirList {
path: path::PathBuf,
pub contents: Vec<JoshutoDirEntry>,
pub metadata: JoshutoMetadata,
- pub index: Option<usize>,
- pub viewport_index: usize,
+ /// The cursor position in this dir list
+ index: Option<usize>,
+ /// The index in this dir list to start with when rendering the list
+ viewport_index: usize,
_need_update: bool,
}
@@ -20,6 +24,7 @@ impl JoshutoDirList {
path: path::PathBuf,
contents: Vec<JoshutoDirEntry>,
index: Option<usize>,
+ viewport_index: usize,
metadata: JoshutoMetadata,
) -> Self {
Self {
@@ -27,7 +32,7 @@ impl JoshutoDirList {
contents,
metadata,
index,
- viewport_index: 0,
+ viewport_index,
_need_update: false,
}
}
@@ -41,17 +46,6 @@ impl JoshutoDirList {
let index = if contents.is_empty() { None } else { Some(0) };
- let viewport_index = match index {
- None => 0,
- Some(index) => {
- if index < options.scroll_offset() {
- 0
- } else {
- index - options.scroll_offset()
- }
- }
- };
-
let metadata = JoshutoMetadata::from(&path)?;
Ok(Self {
@@ -60,10 +54,56 @@ impl JoshutoDirList {
metadata,
_need_update: false,
index,
- viewport_index,
+ viewport_index: if let Some(ix) = index { ix } else { 0 },
})
}
+ pub fn get_index(&self) -> Option<usize> {
+ self.index
+ }
+
+ 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;
+
+ // get scroll buffer size, corrected in case of too small terminal
+ let scroll_offset = if height < 4 {
+ 0
+ } else if options.scroll_offset() * 2 > height - 1 {
+ height / 2 - 1
+ } else {
+ options.scroll_offset()
+ };
+
+ // calculate viewport
+ let viewport_end = self.viewport_index + height;
+ if (viewport_end as i16 - ix as i16 - 1) < scroll_offset as i16 {
+ // cursor too low
+ self.viewport_index = (ix + scroll_offset - height + 1) as usize;
+ } else if (ix as i16 - self.viewport_index as i16) < scroll_offset as i16 {
+ // cursor too high
+ self.viewport_index = cmp::max(ix as i16 - scroll_offset as i16, 0) as usize;
+ }
+ } else {
+ self.viewport_index = 0;
+ }
+ }
+
+ pub fn set_index(
+ &mut self,
+ index: Option<usize>,
+ ui_context: &UiContext,
+ options: &DisplayOption,
+ ) {
+ if index == self.index {
+ return;
+ }
+ self.index = index;
+ if ui_context.layout.len() != 0 {
+ self.update_viewport(ui_context, options);
+ }
+ }
+
pub fn iter(&self) -> Iter<JoshutoDirEntry> {
self.contents.iter()
}
@@ -138,15 +178,9 @@ impl JoshutoDirList {
self.get_curr_mut_(self.index?)
}
- /// For a given number of entries, visible in a UI, this method returns the index of the entry
- /// with which the UI should start to list the entries.
- ///
- /// This method assures that the cursor is always in the viewport of the UI.
- pub fn first_index_for_viewport(&self, viewport_height: usize) -> usize {
- match self.index {
- Some(index) => index / viewport_height as usize * viewport_height as usize,
- None => 0,
- }
+ /// Returns the index of the first entry to be printed in a UI dir list
+ pub fn first_index_for_viewport(&self) -> usize {
+ self.viewport_index
}
fn get_curr_mut_(&mut self, index: usize) -> Option<&mut JoshutoDirEntry> {
diff --git a/src/history.rs b/src/history.rs
index e754705..391cb8d 100644
--- a/src/history.rs
+++ b/src/history.rs
@@ -4,10 +4,16 @@ use std::io;
use std::path::{Path, PathBuf};
use crate::config::option::DisplayOption;
+use crate::context::UiContext;
use crate::fs::{JoshutoDirEntry, JoshutoDirList, JoshutoMetadata};
pub trait DirectoryHistory {
- fn populate_to_root(&mut self, path: &Path, options: &DisplayOption) -> io::Result<()>;
+ fn populate_to_root(
+ &mut self,
+ path: &Path,
+ ui_context: &UiContext,
+ options: &DisplayOption,
+ ) -> io::Result<()>;
fn create_or_soft_update(&mut self, path: &Path, options: &DisplayOption) -> io::Result<()>;
fn create_or_reload(&mut self, path: &Path, options: &DisplayOption) -> io::Result<()>;
fn reload(&mut self, path: &Path, options: &DisplayOption) -> io::Result<()>;
@@ -19,7 +25,12 @@ pub trait DirectoryHistory {
pub type JoshutoHistory = HashMap<PathBuf, JoshutoDirList>;
impl DirectoryHistory for JoshutoHistory {
- fn populate_to_root(&mut self, path: &Path, options: &DisplayOption) -> io::Result<()> {
+ fn populate_to_root(
+ &mut self,
+ path: &Path,
+ ui_context: &UiContext,
+ options: &DisplayOption,
+ ) -> io::Result<()> {
let mut dirlists = Vec::new();
let mut prev: Option<&Path> = None;
@@ -28,7 +39,7 @@ impl DirectoryHistory for JoshutoHistory {
let mut new_dirlist = create_dirlist_with_history(self, curr, options)?;
if let Some(ancestor) = prev.as_ref() {
if let Some(i) = get_index_of_value(&new_dirlist.contents, ancestor) {
- new_dirlist.index = Some(i);
+ new_dirlist.set_index(Some(i), &ui_context, &options);
}
}
dirlists.push(new_dirlist);
@@ -37,7 +48,7 @@ impl DirectoryHistory for JoshutoHistory {
JoshutoDirList::from_path(curr.to_path_buf().clone(), options)?;
if let Some(ancestor) = prev.as_ref() {
if let Some(i) = get_index_of_value(&new_dirlist.contents, ancestor) {
- new_dirlist.index = Some(i);
+ new_dirlist.set_index(Some(i), &ui_context, &options);
}
}
dirlists.push(new_dirlist);
@@ -127,7 +138,7 @@ pub fn create_dirlist_with_history(
None
} else {
match history.get(path) {
- Some(dirlist) => match dirlist.index {
+ Some(dirlist) => match dirlist.get_index() {
Some(i) if i >= contents_len => Some(contents_len - 1),
Some(i) => {
let entry = &dirlist.contents[i];
@@ -143,9 +154,26 @@ pub fn create_dirlist_with_history(
None => Some(0),
}
};
+ let viewport_index: usize = if contents_len == 0 {
+ 0
+ } else {
+ match history.get(path) {
+ Some(dirlist) => match dirlist.first_index_for_viewport() {
+ i if i >= contents_len => contents_len - 1,
+ i => i,
+ },
+ None => 0,
+ }
+ };
let metadata = JoshutoMetadata::from(path)?;
- let dirlist = JoshutoDirList::new(path.to_path_buf(), contents, index, metadata);
+ let dirlist = JoshutoDirList::new(
+ path.to_path_buf(),
+ contents,
+ index,
+ viewport_index,
+ metadata,
+ );
Ok(dirlist)
}
diff --git a/src/preview/preview_default.rs b/src/preview/preview_default.rs
index bda1077..56947b6 100644
--- a/src/preview/preview_default.rs
+++ b/src/preview/preview_default.rs
@@ -44,7 +44,7 @@ pub fn load_preview(context: &mut AppContext, backend: &mut TuiBackend) {
let curr_tab = context.tab_context_ref().curr_tab_ref();
match curr_tab.curr_list_ref() {
Some(curr_list) => {
- if let Some(index) = curr_list.index {
+ if let Some(index) = curr_list.get_index() {
let entry = &curr_list.contents[index];
load_list.push((entry.file_path().to_path_buf(), entry.metadata.clone()));
}
diff --git a/src/run.rs b/src/run.rs
index 7f4cc9f..bfe6b16 100644
--- a/src/run.rs
+++ b/src/run.rs
@@ -12,7 +12,6 @@ use crate::ui::PreviewArea;
use crate::util::input;
use crate::util::to_string::ToString;
-use std::path::{Path, PathBuf};
use std::process;
use std::thread;
use termion::event::{Event, Key};
@@ -26,7 +25,11 @@ pub fn run(
let curr_path = std::env::current_dir()?;
{
// Initialize an initial tab
- let tab = JoshutoTab::new(curr_path, context.config_ref().display_options_ref())?;
+ let tab = JoshutoTab::new(
+ curr_path,
+ context.ui_context_ref(),
+ context.config_ref().display_options_ref(),
+ )?;
context.tab_context_mut().push_tab(tab);
// trigger a preview of child
@@ -36,27 +39,25 @@ pub fn run(
let mut preview_area: Option<PreviewArea> = None;
while context.quit == QuitType::DoNot {
- backend.render(TuiView::new(context));
+ // do the ui
+ if let Ok(area) = backend.terminal_ref().size() {
+ // pre-calculate some ui attributes
+ calculate_ui_context(context, area);
- {
- let config = context.config_ref();
- let preview_options = config.preview_options_ref();
- if let Ok(area) = backend.terminal_ref().size() {
- preview_area = process_preview_on_change(
- &context,
- area,
- preview_area,
- preview_options.preview_shown_hook_script.as_ref(),
- preview_options.preview_removed_hook_script.as_ref(),
- );
- }
+ // render the ui
+ backend.render(TuiView::new(context));
+
+ // invoke preview hooks, if appropriate
+ preview_area = process_preview_on_change(&context, preview_area);
}
+ // wait for an event and pop it
let event = match context.poll_event() {
Ok(event) => event,
Err(_) => return Ok(()), // TODO
};
+ // handle the event
match event {
AppEvent::Termion(Event::Mouse(event)) => {
input::process_mouse(event, context, backend, &keymap_t);
@@ -106,34 +107,41 @@ pub fn run(
}
event => input::process_noninteractive(event, context),
}
+
+ // update the file system supervisor that watches for changes in the FS
context.update_watcher();
- }
+ } // end of main loop
Ok(())
}
-fn process_preview_on_change(
- context: &AppContext,
- area: Rect,
- old_preview_area: Option<PreviewArea>,
- preview_shown_hook_script: Option<&PathBuf>,
- preview_removed_hook_script: Option<&PathBuf>,
-) -> Option<PreviewArea> {
+fn calculate_ui_context(context: &mut AppContext, area: Rect) {
let area = Rect {
y: area.top() + 1,
height: area.height - 2,
..area
};
-
- let constraints = views::get_constraints(&context);
let config = context.config_ref();
let display_options = config.display_options_ref();
+ let constraints = views::get_constraints(&context);
let layout = if display_options.show_borders() {
views::calculate_layout_with_borders(area, constraints)
} else {
views::calculate_layout(area, constraints)
};
- let new_preview_area = views::calculate_preview(&context, layout[2]);
+ context.ui_context_mut().layout = layout;
+}
+
+fn process_preview_on_change(
+ context: &AppContext,
+ old_preview_area: Option<PreviewArea>,
+) -> Option<PreviewArea> {
+ let config = context.config_ref();
+ let preview_options = config.preview_options_ref();
+ let preview_shown_hook_script = preview_options.preview_shown_hook_script.as_ref();
+ let preview_removed_hook_script = preview_options.preview_removed_hook_script.as_ref();
+ let layout = &context.ui_context_ref().layout;
+ let new_preview_area = views::calculate_preview(&context, layout[2]);
match new_preview_area.as_ref() {
Some(new) => {
let should_preview = if let Some(old) = old_preview_area {
diff --git a/src/tab.rs b/src/tab.rs
index 4e2f2e4..190037f 100644
--- a/src/tab.rs
+++ b/src/tab.rs
@@ -1,6 +1,7 @@
use std::path;
use crate::config::option::DisplayOption;
+use crate::context::UiContext;
use crate::fs::JoshutoDirList;
use crate::history::{DirectoryHistory, JoshutoHistory};
@@ -17,9 +18,13 @@ pub struct JoshutoTab {
}
impl JoshutoTab {
- pub fn new(cwd: path::PathBuf, options: &DisplayOption) -> std::io::Result<Self> {
+ pub fn new(
+ cwd: path::PathBuf,
+ ui_context: &UiContext,
+ options: &DisplayOption,
+ ) -> std::io::Result<Self> {
let mut history = JoshutoHistory::new();
- history.populate_to_root(cwd.as_path(), options)?;
+ history.populate_to_root(cwd.as_path(), ui_context, options)?;
Ok(Self { _cwd: cwd, history })
}
@@ -51,7 +56,7 @@ impl JoshutoTab {
pub fn child_list_ref(&self) -> Option<&JoshutoDirList> {
let curr_list = self.curr_list_ref()?;
- let index = curr_list.index?;
+ let index = curr_list.get_index()?;
let path = curr_list.contents[index].file_path();
self.history.get(path)
}
@@ -69,7 +74,7 @@ impl JoshutoTab {
pub fn child_list_mut(&mut self) -> Option<&mut JoshutoDirList> {
let child_path = {
let curr_list = self.curr_list_ref()?;
- let index = curr_list.index?;
+ let index = curr_list.get_index()?;
curr_list.contents[index].file_path().to_path_buf()
};
diff --git a/src/ui/widgets/tui_dirlist.rs b/src/ui/widgets/tui_dirlist.rs
index 9a14e6a..946834b 100644
--- a/src/ui/widgets/tui_dirlist.rs
+++ b/src/ui/widgets/tui_dirlist.rs
@@ -32,8 +32,8 @@ impl<'a> Widget for TuiDirList<'a> {
return;
}
- let curr_index = self.dirlist.index.unwrap();
- let skip_dist = self.dirlist.first_index_for_viewport(area.height as usize);
+ let curr_index = self.dirlist.get_index().unwrap();
+ let skip_dist = self.dirlist.first_index_for_viewport();
let drawing_width = area.width as usize;
@@ -43,26 +43,21 @@ impl<'a> Widget for TuiDirList<'a> {
.enumerate()
.take(area.height as usize)
.for_each(|(i, entry)| {
- let style = style::entry_style(entry);
- print_entry(buf, entry, style, (x + 1, y + i as u16), drawing_width - 1);
- });
-
- // draw selected entry in a different style
- let screen_index = curr_index % area.height as usize;
+ let ix = skip_dist + i;
- let entry = self.dirlist.curr_entry_ref().unwrap();
- let style = style::entry_style(entry).add_modifier(Modifier::REVERSED);
+ let style = if ix == curr_index {
+ style::entry_style(entry).add_modifier(Modifier::REVERSED)
+ } else {
+ style::entry_style(entry)
+ };
- let space_fill = " ".repeat(drawing_width);
- buf.set_string(x, y + screen_index as u16, space_fill.as_str(), style);
+ if ix == curr_index {
+ let space_fill = " ".repeat(drawing_width);
+ buf.set_string(x, y + i as u16, space_fill.as_str(), style);
+ }
- print_entry(
- buf,
- entry,
- style,
- (x + 1, y + screen_index as u16),
- drawing_width - 1,
- );
+ print_entry(buf, entry, style, (x + 1, y + i as u16), drawing_width - 1);
+ });
}
}
diff --git a/src/ui/widgets/tui_dirlist_detailed.rs b/src/ui/widgets/tui_dirlist_detailed.rs
index 7cb0693..f5d07be 100644
--- a/src/ui/widgets/tui_dirlist_detailed.rs
+++ b/src/ui/widgets/tui_dirlist_detailed.rs
@@ -37,7 +37,7 @@ impl<'a> Widget for TuiDirListDetailed<'a> {
let x = area.left();
let y = area.top();
- let curr_index = match self.dirlist.index {
+ let curr_index = match self.dirlist.get_index() {
Some(i) => i,
None => {
let style = Style::default().bg(Color::Red).fg(Color::White);
@@ -47,8 +47,7 @@ impl<'a> Widget for TuiDirListDetailed<'a> {
};
let drawing_width = area.width as usize;
- let skip_dist = self.dirlist.first_index_for_viewport(area.height as usize);
- let screen_index = curr_index % area.height as usize;
+ let skip_dist = self.dirlist.first_index_for_viewport();
let line_num_style = self.display_options.line_nums();
// Length (In chars) of the last entry's index on current page.
// Using this to align all elements
@@ -64,20 +63,38 @@ impl<'a> Widget for TuiDirListDetailed<'a> {
.enumerate()
.take(area.height as usize)
.for_each(|(i, entry)| {
- let style = style::entry_style(entry);
+ let ix = skip_dist + i;
- let line_number_string = match line_num_style {
- LineNumberStyle::Absolute => {
- format!("{:1$} ", skip_dist + i + 1, max_index_length)
+ let style = if ix == curr_index {
+ style::entry_style(entry).add_modifier(Modifier::REVERSED)
+ } else {
+ style::entry_style(entry)
+ };
+
+ let line_number_string = if ix == curr_index {
+ match line_num_style {
+ LineNumberStyle::None => "".to_string(),
+ _ => format!("{:<1$} ", curr_index + 1, max_index_length),
+ }
+ } else {
+ match line_num_style {
+ LineNumberStyle::Absolute => {
+ format!("{:1$} ", ix + 1, max_index_length)
+