summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorqkzk <qu3nt1n@gmail.com>2024-01-01 21:13:55 +0100
committerqkzk <qu3nt1n@gmail.com>2024-01-01 21:13:55 +0100
commit4899d3f7735cfefbf689a7722aa1853e0dec348c (patch)
tree3008ac512c6a2a14d75124c37a62762207280f71
parent449cda8a3e1702a311a43b1dcd7ae000937c74e4 (diff)
WIP mostly working. A GIANT MESSv0.1.25-preview_cache_again
-rw-r--r--src/app/previewer.rs64
-rw-r--r--src/app/status.rs38
-rw-r--r--src/app/tab.rs119
-rw-r--r--src/event/action_map.rs4
-rw-r--r--src/event/event_exec.rs55
-rw-r--r--src/io/display.rs107
-rw-r--r--src/modes/display/preview.rs31
-rw-r--r--src/modes/edit/leave_mode.rs3
8 files changed, 272 insertions, 149 deletions
diff --git a/src/app/previewer.rs b/src/app/previewer.rs
index e780e2b..272690b 100644
--- a/src/app/previewer.rs
+++ b/src/app/previewer.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use std::collections::{HashMap, VecDeque};
use std::path::{Path, PathBuf};
use std::sync::mpsc::{self, TryRecvError};
use std::sync::{Arc, Mutex};
@@ -10,34 +10,66 @@ use anyhow::{anyhow, Context, Result};
use crate::modes::{FileInfo, Preview, Users};
pub struct Previewer {
- tx: mpsc::Sender<Option<PathBuf>>,
- handle: thread::JoinHandle<Result<()>>,
+ pub tx: mpsc::Sender<Option<PathBuf>>,
+ pub handle_receiver: thread::JoinHandle<Result<()>>,
+ pub handle_builder: thread::JoinHandle<Result<()>>,
}
impl Previewer {
pub fn new(preview_cache: Arc<Mutex<PreviewCache>>) -> Self {
let (tx, rx) = mpsc::channel::<Option<PathBuf>>();
+ let queue: Arc<Mutex<VecDeque<PathBuf>>> = Arc::new(Mutex::new(VecDeque::new()));
+ let queue2 = queue.clone();
- let handle = thread::spawn(move || -> Result<()> {
+ let handle_receiver = thread::spawn(move || -> Result<()> {
loop {
match rx.try_recv() {
- Ok(Some(path)) => match preview_cache.lock() {
- Ok(mut preview_cache) => {
- preview_cache.update(&path)?;
- drop(preview_cache);
+ Ok(Some(path)) => match queue2.lock() {
+ Ok(mut queue) => {
+ queue.push_back(path);
+ drop(queue);
}
- Err(error) => return Err(anyhow!("Error locker preview_cache: {error}")),
+ Err(error) => return Err(anyhow!("Error locking queue: {error}")),
},
Ok(_) | Err(TryRecvError::Disconnected) => {
crate::log_info!("terminating previewer");
break;
}
- Err(TryRecvError::Empty) => {}
+ Err(TryRecvError::Empty) => {
+ thread::sleep(Duration::from_millis(33));
+ }
}
}
Ok(())
});
- Self { tx, handle }
+
+ let handle_builder = thread::spawn(move || loop {
+ match queue.lock() {
+ Err(error) => return Err(anyhow!("error locking queue lock: {error}")),
+ Ok(mut queue) => {
+ match queue.pop_front() {
+ Some(path) => match preview_cache.lock() {
+ Ok(mut preview_cache) => {
+ preview_cache.update(&path)?;
+ drop(preview_cache);
+ }
+ Err(error) => {
+ return Err(anyhow!("Error locking preview_cache: {error}"))
+ }
+ },
+ None => {
+ thread::sleep(Duration::from_millis(33));
+ }
+ };
+ drop(queue);
+ }
+ }
+ });
+ Self {
+ tx,
+ handle_receiver,
+ handle_builder,
+ }
}
}
@@ -64,6 +96,7 @@ impl PreviewCache {
/// - Preview fail.
pub fn update(&mut self, path: &Path) -> Result<bool> {
if self.cache.contains_key(path) {
+ crate::log_info!("key {path} already in cache", path = path.display());
return Ok(false);
};
self.add_preview(path)?;
@@ -71,15 +104,22 @@ impl PreviewCache {
Ok(true)
}
+ pub fn add_made_preview(&mut self, path: &Path, preview: Preview) {
+ self.cache.insert(path.to_path_buf(), preview);
+ self.paths.push(path.to_path_buf());
+ self.limit_size();
+ }
+
fn add_preview(&mut self, path: &Path) -> Result<()> {
self.cache
.insert(path.to_path_buf(), Self::make_preview(path)?);
self.paths.push(path.to_path_buf());
+ crate::log_info!("added {path} to cache", path = path.display());
Ok(())
}
fn make_preview(path: &Path) -> Result<Preview> {
- Preview::file(&FileInfo::from_path_with_name(
+ Preview::new(&FileInfo::from_path_with_name(
path,
&path.file_name().context("")?.to_string_lossy(),
&Users::default(),
diff --git a/src/app/status.rs b/src/app/status.rs
index b93ac32..1d38167 100644
--- a/src/app/status.rs
+++ b/src/app/status.rs
@@ -33,7 +33,6 @@ use crate::io::{
use crate::modes::Content;
use crate::modes::Display;
use crate::modes::Edit;
-use crate::modes::FileKind;
use crate::modes::InputSimple;
use crate::modes::IsoDevice;
use crate::modes::Menu;
@@ -365,23 +364,19 @@ impl Status {
pub fn set_second_pane_for_preview(&mut self) -> Result<()> {
log_info!("set_second_pane_for_preview enter");
if !Session::display_wide_enough(self.term_size()?.0) {
- self.tabs[1].preview = Preview::empty();
+ self.tabs[0].option_preview = None;
return Ok(());
}
log_info!("set_second_pane_for_preview alive");
- self.tabs[1].set_display_mode(Display::Preview);
self.set_edit_mode(1, Edit::Nothing)?;
- let fileinfo = self.tabs[0]
- .current_file()
- .context("force preview: No file to select")?;
- let preview = match fileinfo.file_kind {
- FileKind::Directory => Preview::directory(&fileinfo, &self.tabs[0].users),
- _ => Preview::file(&fileinfo),
+ self.tabs[1].set_display_mode(Display::Preview);
+ let path = self.tabs[0].current_file()?.path.to_path_buf();
+ match self.preview_cache.lock() {
+ Err(error) => return Err(anyhow!("error locking preview_cache: {error}")),
+ Ok(mut preview_cache) => preview_cache.update(&path)?,
};
- self.tabs[1].preview = preview.unwrap_or_default();
-
- self.tabs[1].window.reset(self.tabs[1].preview.len());
+ self.tabs[0].option_preview = Some(path);
log_info!("set_second_pane_for_preview exit");
Ok(())
}
@@ -779,7 +774,7 @@ impl Status {
if let Ok(output) =
execute_and_capture_output_with_path(executable, current_directory, &params)
{
- self.preview_command_output(output, shell_command);
+ self.preview_command_output(output, shell_command)?;
}
Ok(true)
}
@@ -909,9 +904,8 @@ impl Status {
self.current_tab().directory_of_selected()?,
)?;
self.menu.clear_sudo_attributes()?;
- self.preview_command_output(output, sudo_command.to_owned());
- // self.refresh_status()
- Ok(())
+ self.preview_command_output(output, sudo_command.to_owned())?;
+ self.refresh_status()
}
/// Dispatch the known password depending of which component set
@@ -937,13 +931,21 @@ impl Status {
}
/// Set the display to preview a command output
- pub fn preview_command_output(&mut self, output: String, command: String) {
+ pub fn preview_command_output(&mut self, output: String, command: String) -> Result<()> {
log_info!("output {output}");
let _ = self.reset_edit_mode();
self.current_tab_mut().set_display_mode(Display::Preview);
let preview = Preview::cli_info(&output, command);
self.current_tab_mut().window.reset(preview.len());
- self.current_tab_mut().preview = preview;
+ match self.preview_cache.lock() {
+ Err(error) => return Err(anyhow!("Error locking preview_cache: {error}")),
+ Ok(mut preview_cache) => {
+ let path = std::path::PathBuf::from("command");
+ self.tabs[self.index].set_preview(&path);
+ preview_cache.add_made_preview(&path, preview);
+ }
+ }
+ Ok(())
}
/// Set the nvim listen address from what the user typed.
diff --git a/src/app/tab.rs b/src/app/tab.rs
index 6bccf28..d62177c 100644
--- a/src/app/tab.rs
+++ b/src/app/tab.rs
@@ -9,15 +9,14 @@ use crate::common::{
};
use crate::io::Args;
use crate::modes::Content;
+use crate::modes::ContentWindow;
use crate::modes::Directory;
use crate::modes::FileInfo;
use crate::modes::FilterKind;
use crate::modes::History;
-use crate::modes::Preview;
use crate::modes::Selectable;
use crate::modes::SortKind;
use crate::modes::Users;
-use crate::modes::{ContentWindow, FileKind};
use crate::modes::{Display, Edit};
use crate::modes::{Go, To, Tree};
@@ -67,9 +66,6 @@ pub struct Tab {
pub directory: Directory,
/// Tree representation of the same path
pub tree: Tree,
- /// Lines of the previewed files.
- /// Empty if not in preview mode.
- pub preview: Preview,
/// The edit mode the application is currenty in.
/// Most of the time is spent in `EditMode::Nothing`
@@ -92,6 +88,7 @@ pub struct Tab {
pub history: History,
/// Users & groups
pub users: Users,
+ pub option_preview: Option<path::PathBuf>,
}
impl Tab {
@@ -123,11 +120,11 @@ impl Tab {
let display_mode = Display::default();
let edit_mode = Edit::Nothing;
let mut window = ContentWindow::new(directory.content.len(), height);
- let preview = Preview::Empty;
let history = History::default();
let searched = None;
let index = directory.select_file(&path);
let tree = Tree::default();
+ let option_preview = None;
window.scroll_to(index);
Ok(Self {
@@ -136,12 +133,12 @@ impl Tab {
window,
directory,
height,
- preview,
searched,
history,
users,
tree,
settings,
+ option_preview,
})
}
@@ -180,7 +177,7 @@ impl Tab {
fn display_len(&self) -> usize {
match self.display_mode {
Display::Tree => self.tree.display_len(),
- Display::Preview => self.preview.len(),
+ Display::Preview => usize::MAX,
Display::Directory => self.directory.len(),
}
}
@@ -232,7 +229,7 @@ impl Tab {
/// Refresh everything but the view
pub fn refresh_params(&mut self) -> Result<()> {
- self.preview = Preview::empty();
+ self.option_preview = None;
if matches!(self.display_mode, Display::Tree) {
self.make_tree(None)?;
} else {
@@ -271,7 +268,7 @@ impl Tab {
/// Change the display mode.
pub fn set_display_mode(&mut self, new_display_mode: Display) {
- self.reset_preview();
+ self.option_preview = None;
self.display_mode = new_display_mode
}
@@ -311,34 +308,39 @@ impl Tab {
Ok(())
}
- /// Creates a new preview for the selected file.
- pub fn make_preview(&mut self) -> Result<()> {
- if self.directory.is_empty() {
- return Ok(());
- }
- let Ok(file_info) = self.current_file() else {
- return Ok(());
- };
- match file_info.file_kind {
- FileKind::NormalFile => {
- let preview = Preview::file(&file_info).unwrap_or_default();
- self.set_display_mode(Display::Preview);
- self.window.reset(preview.len());
- self.preview = preview;
- }
- FileKind::Directory => self.toggle_tree_mode()?,
- _ => (),
- }
-
- Ok(())
+ pub fn set_preview(&mut self, path: &path::Path) {
+ self.window.reset(usize::MAX);
+ self.option_preview = Some(path.to_path_buf());
}
+ /// Creates a new preview for the selected file.
+ // pub fn make_preview(&mut self) -> Result<()> {
+ // if self.directory.is_empty() {
+ // return Ok(());
+ // }
+ // let Ok(file_info) = self.current_file() else {
+ // return Ok(());
+ // };
+ // match file_info.file_kind {
+ // FileKind::NormalFile => {
+ // let preview = Preview::file(&file_info).unwrap_or_default();
+ // self.set_display_mode(Display::Preview);
+ // self.window.reset(preview.len());
+ // self.preview = preview;
+ // }
+ // FileKind::Directory => self.toggle_tree_mode()?,
+ // _ => (),
+ // }
+ //
+ // Ok(())
+ // }
+
/// Reset the preview to empty. Used to save some memory.
- fn reset_preview(&mut self) {
- if matches!(self.display_mode, Display::Preview) {
- self.preview = Preview::empty();
- }
- }
+ // fn reset_preview(&mut self) {
+ // if matches!(self.display_mode, Display::Preview) {
+ // self.preview = Preview::empty();
+ // }
+ // }
/// Refresh the folder, reselect the last selected file, move the window to it.
pub fn refresh_and_reselect_file(&mut self) -> Result<()> {
@@ -665,36 +667,39 @@ impl Tab {
/// Move the preview to the bottom
pub fn preview_go_bottom(&mut self) {
- self.window
- .scroll_to(self.preview.len().checked_sub(1).unwrap_or_default())
+ // todo!("preview go bottom shouldn't be here");
+ // self.window
+ // .scroll_to(self.preview.len().checked_sub(1).unwrap_or_default())
}
/// Move 30 lines up or an image in Ueberzug.
pub fn preview_page_up(&mut self) {
- match &mut self.preview {
- Preview::Ueberzug(ref mut image) => image.up_one_row(),
- _ => {
- if self.window.top > 0 {
- let skip = min(self.window.top, 30);
- self.window.bottom -= skip;
- self.window.top -= skip;
- }
- }
- }
+ // match &mut self.preview {
+ // Preview::Ueberzug(ref mut image) => image.up_one_row(),
+ // _ => {
+ // if self.window.top > 0 {
+ // let skip = min(self.window.top, 30);
+ // self.window.bottom -= skip;
+ // self.window.top -= skip;
+ // }
+ // }
+ // }
}
/// Move down 30 rows except for Ueberzug where it moves 1 image down
pub fn preview_page_down(&mut self) {
- match &mut self.preview {
- Preview::Ueberzug(ref mut image) => image.down_one_row(),
- _ => {
- if self.window.bottom < self.preview.len() {
- let skip = min(self.preview.len() - self.window.bottom, 30);
- self.window.bottom += skip;
- self.window.top += skip;
- }
- }
- }
+ // todo!("preview page up shouldn't be there");
+ // match &mut self.preview {
+ // Preview::Ueberzug(ref mut image) => image.down_one_row(),
+ // _ => {
+ // if self.window.bottom < self.preview.len() {
+ // let skip = min(self.preview.len() - self.window.bottom, 30);
+ // let skip = 30;
+ // self.window.bottom += skip;
+ // self.window.top += skip;
+ // }
+ // }
+ // }
}
/// Select a given row, if there's something in it.
diff --git a/src/event/action_map.rs b/src/event/action_map.rs
index 1a96be7..5f9df52 100644
--- a/src/event/action_map.rs
+++ b/src/event/action_map.rs
@@ -145,7 +145,7 @@ impl ActionMap {
Self::Home => EventAction::home(status),
Self::Jump => EventAction::jump(status),
Self::KeyHome => EventAction::key_home(status),
- Self::Log => EventAction::log(current_tab),
+ Self::Log => EventAction::log(status),
Self::LazyGit => EventAction::lazygit(status),
Self::MarksJump => EventAction::marks_jump(status),
Self::MarksNew => EventAction::marks_new(status),
@@ -169,7 +169,7 @@ impl ActionMap {
Self::OpenFile => EventAction::open_file(status),
Self::PageDown => EventAction::page_down(status),
Self::PageUp => EventAction::page_up(status),
- Self::Preview => EventAction::preview(current_tab),
+ Self::Preview => EventAction::preview(status),
Self::PreviousSibling => EventAction::previous_sibling(current_tab),
Self::Quit => EventAction::quit(status),
Self::RefreshIfNeeded => EventAction::refresh_if_needed(current_tab),
diff --git a/src/event/event_exec.rs b/src/event/event_exec.rs
index 4e80862..d7b28a1 100644
--- a/src/event/event_exec.rs
+++ b/src/event/event_exec.rs
@@ -1,6 +1,7 @@
use std::borrow::Borrow;
use std::path;
+use anyhow::anyhow;
use anyhow::{Context, Result};
use crate::app::Status;
@@ -15,7 +16,6 @@ use crate::io::execute_without_output_with_path;
use crate::io::read_log;
use crate::log_info;
use crate::log_line;
-use crate::modes::help_string;
use crate::modes::lsblk_and_cryptsetup_installed;
use crate::modes::open_tui_program;
use crate::modes::Display;
@@ -31,6 +31,7 @@ use crate::modes::Preview;
use crate::modes::RemovableDevices;
use crate::modes::Selectable;
use crate::modes::MOCP;
+use crate::modes::{help_string, Content};
/// Links events from tuikit to custom actions.
/// It mutates `Status` or its children `Tab`.
@@ -135,8 +136,19 @@ impl EventAction {
/// Every file can be previewed. See the `crate::enum::Preview` for
/// more details on previewinga file.
/// Does nothing if the directory is empty.
- pub fn preview(tab: &mut Tab) -> Result<()> {
- tab.make_preview()
+ pub fn preview(status: &mut Status) -> Result<()> {
+ match status.preview_cache.lock() {
+ Err(error) => return Err(anyhow!("error lokcing preview cache: {error}")),
+ Ok(mut preview_cache) => {
+ let path = std::path::PathBuf::from(&status.current_tab().current_file_string()?);
+ status.tabs[status.index].set_display_mode(Display::Preview);
+ preview_cache.update(&path)?;
+ status.tabs[status.index].option_preview = Some(path.to_path_buf());
+ }
+ };
+ Ok(())
+
+ // tab.make_preview()
}
/// Toggle the display of hidden files.
@@ -371,21 +383,36 @@ impl EventAction {
pub fn help(status: &mut Status, binds: &Bindings) -> Result<()> {
let help = help_string(binds, &status.internal_settings.opener);
status.current_tab_mut().set_display_mode(Display::Preview);
- status.current_tab_mut().preview = Preview::help(&help);
- let len = status.current_tab().preview.len();
- status.current_tab_mut().window.reset(len);
+ let preview = Preview::help(&help);
+ status.current_tab_mut().window.reset(preview.len());
+ match status.preview_cache.lock() {
+ Err(error) => return Err(anyhow!("Error locking preview_cache: {error}")),
+ Ok(mut preview_cache) => {
+ let path = std::path::PathBuf::from("help");
+ status.tabs[status.index].set_preview(&path);
+ preview_cache.add_made_preview(&path, preview);
+ }
+ }
Ok(())
}
/// Display the last actions impacting the file tree
- pub fn log(tab: &mut Tab) -> Result<()> {
+ pub fn log(status: &mut Status) -> Result<()> {
let Ok(log) = read_log() else {
return Ok(());
};
- tab.set_display_mode(Display::Preview);
- tab.preview = Preview::log(log);
- tab.window.reset(tab.preview.len());
- tab.preview_go_bottom();
+ status.current_tab_mut().set_display_mode(Display::Preview);
+
+ let preview = Preview::log(log);
+ status.current_tab_mut().window.reset(preview.len());
+ match status.preview_cache.lock() {
+ Err(error) => return Err(anyhow!("Error locking preview_cache: {error}")),
+ Ok(mut preview_cache) => {
+ let path = std::path::PathBuf::from("log");
+ status.tabs[status.index].set_preview(&path);
+ preview_cache.add_made_preview(&path, preview);
+ }
+ }
Ok(())
}
@@ -571,6 +598,12 @@ impl EventAction {
}
fn move_display_down(status: &mut Status) -> Result<()> {
+ for i in 0..100 {
+ let index =
+ (status.current_tab().directory.index + i) % status.current_tab().directory.len();
+ let path = &status.current_tab().directory.content()[index].path;
+ status.previewer.tx.send(Some(path.to_path_buf()))?;
+ }
let tab = status.current_tab_mut();
match tab.display_mode {
Display::Directory => tab.normal_down_one_row(),
diff --git a/src/io/display.rs b/src/io/display.rs
index 6558aae..95a2a47 100644
--- a/src/io/display.rs
+++ b/src/io/display.rs
@@ -53,15 +53,17 @@ macro_rules! enumerated_colored_iter {
/// Draw every line of the preview
macro_rules! impl_preview {
- ($text:ident, $tab:ident, $length:ident, $canvas:ident, $line_number_width:ident, $window:ident, $height:ident) => {
+ ($text:ident, $tab:ident, $length:ident, $canvas:ident, $line_number_width:ident, $window:ident, $height:ident) => {{
+ let mut window = $window.to_owned();
+ window.reset($length);
for (i, line) in (*$text).window($window.top, $window.bottom, $length) {
- let row = calc_line_row(i, $window);
+ let row = calc_line_row(i, &window);
if row > $height {
break;
}
$canvas.print(row, $line_number_width + 3, line)?;
}
- };
+ }};
}
/// At least 120 chars width to display 2 tabs.
@@ -380,15 +382,29 @@ impl<'a> WinMain<'a> {
window: &ContentWindow,
canvas: &mut dyn Canvas,
) -> Result<Option<usize>> {
- let length = tab.preview.len();
- let line_number_width = length.to_string().len();
+ log_info!("draw_preview enter");
let height = canvas.height()?;
+ let Some(path) = &tab.option_preview else {
+ return Ok(None);
+ };
match self.status.preview_cache.lock() {
Err(error) => return Err(anyhow!("Error locking preview cache: {error}")),
- Ok(preview_cache) => {
- match preview_cache.read(self.status.tabs[self.status.index].current_path()) {
- None => (),
- Some(preview) => match preview {
+ Ok(preview_cache) => match preview_cache.read(path) {
+ None => {
+ log_info!(
+ "no preview found for {path} in cache",
+ path = tab.current_path().display()
+ );
+ }
+ Some(preview) => {
+ log_info!(
+ "displaying preview for {path}",
+ path = tab.current_file()?.path.display()
+ );
+ let length = preview.len();
+ log_info!("preview has {length} lines");
+ let line_number_width = length.to_string().len();
+ match preview {
Preview::Syntaxed(syntaxed) => {
self.draw_syntaxed(syntaxed, length, canvas, line_number_width, window)?
}
@@ -479,9 +495,9 @@ impl<'a> WinMain<'a> {
}
Preview::Empty => (),
- },
+ }
}
- }
+ },
}
Ok(None)
}
@@ -494,8 +510,10 @@ impl<'a> WinMain<'a> {
line_number_width: usize,
window: &ContentWindow,
) -> Result<()> {
+ let mut window = window.to_owned();
+ window.reset(syntaxed.len());
for (i, vec_line) in (*syntaxed).window(window.top, window.bottom, length) {
- let row_position = calc_line_row(i, window);
+ let row_position = calc_line_row(i, &window);
Self::draw_line_number(row_position, i + 1, canvas)?;
for token in vec_line.iter() {
token.print(canvas, row_position, line_number_width)?;
@@ -511,11 +529,13 @@ impl<'a> WinMain<'a> {
canvas: &mut dyn Canvas,
window: &ContentWindow,
) -> Result<()> {
+ let mut window = window.to_owned();
+ window.reset(bin.len());
let height = canvas.height()?;
let line_number_width_hex = format!("{:x}", bin.len() * 16).len();
for (i, line) in (*bin).window(window.top, window.bottom, length) {
- let row = calc_line_row(i, window);
+ let row = calc_line_row(i, &window);
if row > height {
break;
}
@@ -549,6 +569,8 @@ impl<'a> WinMain<'a> {
window: &ContentWindow,
canvas: &mut dyn Canvas,
) -> Result<()> {
+ let mut window = window.to_owned();
+ window.reset(tree_preview.len());
let height = canvas.height()?;
let tree_content = tree_preview.tree.displayable();
let content = tree_content.lines();
@@ -582,9 +604,11 @@ impl<'a> WinMain<'a> {
canvas: &mut dyn Canvas,
window: &ContentWindow,
) -> Result<()> {
+ let mut window = window.to_owned();
+ window.reset(colored_text.len());
let height = canvas.height()?;
for (i, line) in colored_text.window(window.top, window.bottom, length) {
- let row = calc_line_row(i, window);
+ let row = calc_line_row(i, &window);
if row > height {
break;
}
@@ -597,12 +621,13 @@ impl<'a> WinMain<'a> {
}
fn draw_preview_as_second_pane(&self, canvas: &mut dyn Canvas) -> Result<()> {
- let tab = &self.status.tabs[1];
- self.draw_preview(tab, &tab.window, canvas)?;
+ let left = &self.status.tabs[0];
+ let right = &self.status.tabs[1];
+ self.draw_preview(left, &right.window, canvas)?;
draw_colored_strings(
0,
0,
- &PreviewHeader::make_default_preview(self.status, tab),
+ &PreviewHeader::make_default_preview(self.status, right, &Preview::empty()),
canvas,
false,
)?;
@@ -662,15 +687,29 @@ struct PreviewHeader;
impl PreviewHeader {
fn make_preview(status: &Status, tab: &Tab) -> Vec<String> {
- match &tab.preview {
- Preview::Text(text_content) => match text_content.kind {
- TextKind::HELP => Self::make_help(),
- TextKind::LOG => Self::make_log(),
- _ => Self::make_default_preview(status, tab),
- },
- Preview::ColoredText(colored_text) => Self::make_colored_text(colored_text),
- _ => Self::make_default_preview(status, tab),
+ match status.preview_cache.lock() {
+ Err(_) => (),
+ Ok(preview_cache) => {
+ if let Some(path) = &tab.option_preview {
+ if let Some(preview) = preview_cache.read(path) {
+ match &preview {
+ Preview::Text(text_content) => {
+ return match text_content.kind {
+ TextKind::HELP => Self::make_help(),
+ TextKind::LOG => Self::make_log(),
+ _ => Self::make_default_preview(status, tab, preview),
+ }
+ }
+ Preview::ColoredText(colored_text) => {
+ return Self::make_colored_text(colored_text)
+ }
+ _ => return Self::make_default_preview(status, tab, preview),
+ }
+ }
+ }
+ }
}
+ vec![]
}
fn make_help() -> Vec<String> {
@@ -695,25 +734,25 @@ impl PreviewHeader {
]
}
- fn _pick_previewed_fileinfo(status: &Status) -> Result<FileInfo> {
+ fn _pick_previewed_fileinfo(status: &Status) -> &Option<PathBuf> {
if status.display_settings.dual() && status.display_settings.preview() {
- status.tabs[0].current_file()
+ &status.tabs[0].option_preview
} else {
- status.current_tab().current_file()
+ &status.current_tab().option_preview
}
}
- fn make_default_preview(status: &Status, tab: &Tab) -> Vec<String> {
- if let Ok(fileinfo) = Self::_pick_previewed_fileinfo(status) {
+ fn make_default_preview(status: &Status, tab: &Tab, preview: &Preview) -> Vec<String> {
+ if let Some(path) = Self::_pick_previewed_fileinfo(status) {
let mut strings = vec![" Preview ".to_owned()];
- if !tab.preview.is_empty() {
- let index = match &tab.preview {
+ if !preview.is_empty() {
+ let index = match preview {
Preview::Ueberzug(image) => image.index + 1,
_ => tab.window.bottom,
};
- strings.push(format!(" {index} / {len} ", len = tab.preview.len()));
+ strings.push(format!(" {index} / {len} ", len = preview.len()));
};
- strings.push(format!(" {} ", fileinfo.path.display()));
+ strings.push(format!(" {path} ", path = path.display()));
strings
} else {
vec!["".to_owned()]
diff --git a/src/modes/display/preview.rs b/src/modes/display/preview.rs
index ec899a8..1903123 100644
--- a/src/modes/display/preview.rs
+++ b/src/modes/display/preview.rs
@@ -131,15 +131,20 @@ impl Preview {
/// it to the display method.
/// Directories aren't handled there since we need more arguments to create
/// their previews.
- pub fn file(file_info: &FileInfo) -> Result<Self> {
+ pub fn new(file_info: &FileInfo) -> Result<Self> {
clear_tmp_file();
match file_info.file_kind {
- FileKind::Directory => Err(anyhow!(
- "{path} is a directory",
- path = file_info.path.display()
- )),
+ FileKind::Directory => Self::directory(file_info, &Users::default()),
+ // FileKind::Directory => Err(anyhow!(
+ // "{path} is a directory",
+ // path = file_info.path.display()
+ // )),
FileKind::NormalFile => {
let extension = &file_info.extension.to_lowercase();
+ log_info!(
+ "building preview for {filename}",
+ filename = file_info.filename
+ );
match ExtensionKind::matcher(extension) {
ExtensionKind::Archive => Ok(Self::Archive(ArchiveContent::new(
&file_info.path,
@@ -355,7 +360,7 @@ impl Socket {
}
}
- fn len(&self) -> usize {
+ pub fn len(&self) -> usize {
self.length
}
}
@@ -391,7 +396,7 @@ impl BlockDevice {
}
}