use std::cmp::min;
use std::fmt::Write as _;
use std::fs::metadata;
use std::io::Cursor;
use std::io::{BufRead, BufReader, Read};
use std::iter::{Enumerate, Skip, Take};
use std::panic;
use std::path::{Path, PathBuf};
use std::slice::Iter;
use anyhow::{anyhow, Context, Result};
use content_inspector::{inspect, ContentType};
use log::info;
use pdf_extract;
use syntect::easy::HighlightLines;
use syntect::highlighting::{Style, ThemeSet};
use syntect::parsing::{SyntaxReference, SyntaxSet};
use tuikit::attr::{Attr, Color};
use users::UsersCache;
use crate::config::Colors;
use crate::constant_strings_paths::THUMBNAIL_PATH;
use crate::content_window::ContentWindow;
use crate::decompress::list_files_zip;
use crate::fileinfo::{FileInfo, FileKind};
use crate::filter::FilterKind;
use crate::opener::execute_and_capture_output_without_check;
use crate::status::Status;
use crate::tree::{ColoredString, Tree};
use crate::utils::filename_from_path;
/// Different kind of preview used to display some informaitons
/// About the file.
/// We check if it's an archive first, then a pdf file, an image, a media file
#[derive(Default)]
pub enum Preview {
Syntaxed(HLContent),
Text(TextContent),
Binary(BinaryContent),
Pdf(PdfContent),
Archive(ZipContent),
Ueberzug(Ueberzug),
Media(MediaContent),
Directory(Directory),
Iso(Iso),
Diff(Diff),
#[default]
Empty,
}
#[derive(Clone, Default)]
pub enum TextKind {
HELP,
LOG,
#[default]
TEXTFILE,
}
impl Preview {
const CONTENT_INSPECTOR_MIN_SIZE: usize = 1024;
/// Creates a new preview instance based on the filekind and the extension of
/// the file.
/// Sometimes it reads the content of the file, sometimes it delegates
/// it to the display method.
pub fn new(
file_info: &FileInfo,
users_cache: &UsersCache,
status: &Status,
colors: &Colors,
) -> Result<Self> {
match file_info.file_kind {
FileKind::Directory => Ok(Self::Directory(Directory::new(
&file_info.path,
users_cache,
colors,
&status.selected_non_mut().filter,
status.selected_non_mut().show_hidden,
Some(2),
)?)),
FileKind::NormalFile => match file_info.extension.to_lowercase().as_str() {
e if is_ext_compressed(e) => Ok(Self::Archive(ZipContent::new(&file_info.path)?)),
e if is_ext_pdf(e) => Ok(Self::Pdf(PdfContent::new(&file_info.path))),
e if is_ext_image(e) => Ok(Self::Ueberzug(Ueberzug::image(&file_info.path)?)),
e if is_ext_audio(e) => Ok(Self::Media(MediaContent::new(&file_info.path)?)),
e if is_ext_video(e) => {
Ok(Self::Ueberzug(Ueberzug::video_thumbnail(&file_info.path)?))
}
e if is_ext_font(e) => {
Ok(Self::Ueberzug(Ueberzug::font_thumbnail(&file_info.path)