From 989667c2604c25bdc33391f84f543b2b454c7386 Mon Sep 17 00:00:00 2001 From: sxyazi Date: Tue, 18 Jul 2023 23:21:35 +0800 Subject: [PATCH] feat: plain text preview --- src/core/manager/preview.rs | 37 +++++++++++++++++++------------------ src/misc/fs.rs | 15 +-------------- 2 files changed, 20 insertions(+), 32 deletions(-) diff --git a/src/core/manager/preview.rs b/src/core/manager/preview.rs index 2b92a532..52672390 100644 --- a/src/core/manager/preview.rs +++ b/src/core/manager/preview.rs @@ -1,12 +1,12 @@ -use std::{fs::File, io::BufReader, path::{Path, PathBuf}, sync::OnceLock}; +use std::{fs::File, io::{BufRead, BufReader}, path::{Path, PathBuf}, sync::OnceLock}; -use anyhow::{anyhow, Context, Result}; +use anyhow::{anyhow, Result}; use image::imageops::FilterType; -use syntect::{easy::HighlightLines, highlighting::{Theme, ThemeSet}, parsing::SyntaxSet, util::as_24_bit_terminal_escaped}; +use syntect::{easy::HighlightFile, highlighting::{Theme, ThemeSet}, parsing::SyntaxSet, util::as_24_bit_terminal_escaped}; use tokio::{fs, task::JoinHandle}; use super::{ALL_RATIO, PREVIEW_BORDER, PREVIEW_PADDING, PREVIEW_RATIO}; -use crate::{config::{PREVIEW, THEME}, core::{adapter::Kitty, external, files::{Files, FilesOp}, tasks::Precache}, emit, misc::{first_n_lines, tty_ratio, tty_size, MimeKind}}; +use crate::{config::{PREVIEW, THEME}, core::{adapter::Kitty, external, files::{Files, FilesOp}, tasks::Precache}, emit, misc::{tty_ratio, tty_size, MimeKind}}; static SYNTECT_SYNTAX: OnceLock = OnceLock::new(); static SYNTECT_THEME: OnceLock = OnceLock::new(); @@ -137,7 +137,6 @@ impl Preview { pub async fn highlight(path: &Path) -> Result { let syntax = SYNTECT_SYNTAX.get_or_init(|| SyntaxSet::load_defaults_newlines()); - let theme = SYNTECT_THEME.get_or_init(|| { let from_file = || -> Result { let file = File::open(&THEME.preview.syntect_theme)?; @@ -146,22 +145,24 @@ impl Preview { from_file().unwrap_or_else(|_| ThemeSet::load_defaults().themes["base16-ocean.dark"].clone()) }); - let ext = path.extension().context("no extension found")?.to_string_lossy().to_string(); - - let lines = first_n_lines(path, Self::size().1 as usize).await?; + let path = path.to_path_buf(); + let spaces = " ".repeat(PREVIEW.tab_size as usize); tokio::task::spawn_blocking(move || -> Result { - let mut buf = "".to_string(); - if let Some(syn) = syntax.find_syntax_by_extension(&ext) { - let mut h = HighlightLines::new(syn, theme); - let tab = " ".repeat(PREVIEW.tab_size as usize); - for line in lines { - let line = line.replace('\t', &tab); - let ranges = h.highlight_line(&line, &syntax)?; - buf.push_str(&as_24_bit_terminal_escaped(&ranges, false)); - buf.push('\n'); - } + let mut h = HighlightFile::new(path, syntax, theme)?; + let mut line = String::new(); + let mut buf = String::new(); + + let mut i = Self::size().1 as usize; + while i > 0 && h.reader.read_line(&mut line)? > 0 { + i -= 1; + line = line.replace('\t', &spaces); + let regions = h.highlight_lines.highlight_line(&line, syntax)?; + buf.push_str(&as_24_bit_terminal_escaped(®ions[..], false)); + line.clear(); } + + buf.push_str("\x1b[0m"); Ok(buf) }) .await? diff --git a/src/misc/fs.rs b/src/misc/fs.rs index de6f0a8d..4af8364b 100644 --- a/src/misc/fs.rs +++ b/src/misc/fs.rs @@ -1,20 +1,7 @@ use std::{collections::VecDeque, path::Path}; use anyhow::Result; -use tokio::{fs::{self, File}, io::{self, AsyncBufReadExt, BufReader}, select, sync::{mpsc, oneshot}, time}; - -pub async fn first_n_lines(path: &Path, n: usize) -> Result> { - let mut lines = Vec::new(); - let mut it = BufReader::new(File::open(path).await?).lines(); - for _ in 0..n { - if let Some(line) = it.next_line().await? { - lines.push(line); - } else { - break; - } - } - Ok(lines) -} +use tokio::{fs, io, select, sync::{mpsc, oneshot}, time}; pub async fn calculate_size(path: &Path) -> u64 { let mut total = 0;