feat: more syntaxes and themes for highlighting + configuration

This commit is contained in:
Alexandre Pasmantier 2024-11-09 19:44:56 +01:00
parent 2dbbd0c4a3
commit 759815ae24
12 changed files with 495 additions and 50 deletions

View File

@ -9,6 +9,12 @@ use_nerd_font_icons = false
# How much space to allocate for the UI (in percentage of the screen)
ui_scale = 80
# Previewers settings
# ----------------------------------------------------------------------------
[previewers.file]
# The theme to use for syntax highlighting
theme = "Catppuccin Mocha"
# Keybindings
# ----------------------------------------------------------------------------
#

291
Cargo.lock generated
View File

@ -50,6 +50,15 @@ version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
[[package]]
name = "ansi_colours"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14eec43e0298190790f41679fe69ef7a829d2a2ddd78c8c00339e84710e435fe"
dependencies = [
"rgb",
]
[[package]]
name = "anstream"
version = "0.6.18"
@ -161,6 +170,43 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bat"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dcc9e5637c2330d8eb7b920f2aa5d9e184446c258466f825ea1412c7614cc86"
dependencies = [
"ansi_colours",
"bincode",
"bugreport",
"bytesize",
"clap",
"clircle",
"console",
"content_inspector",
"encoding_rs",
"etcetera",
"flate2",
"git2",
"globset",
"grep-cli",
"home",
"nu-ansi-term 0.49.0",
"once_cell",
"path_abs",
"plist",
"regex",
"semver",
"serde",
"serde_yaml",
"shell-words",
"syntect",
"thiserror",
"unicode-width 0.1.14",
"walkdir",
"wild",
]
[[package]]
name = "better-panic"
version = "0.3.0"
@ -221,6 +267,23 @@ dependencies = [
"serde",
]
[[package]]
name = "bugreport"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "535120b8182547808081a66f1f77a64533c780b23da26763e0ee34dfb94f98c9"
dependencies = [
"git-version",
"shell-escape",
"sys-info",
]
[[package]]
name = "bytemuck"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d"
[[package]]
name = "byteorder"
version = "1.5.0"
@ -233,6 +296,12 @@ version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da"
[[package]]
name = "bytesize"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc"
[[package]]
name = "calloop"
version = "0.13.0"
@ -312,6 +381,8 @@ version = "1.1.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baee610e9452a8f6f0a1b6194ec09ff9e2d85dea54432acdae41aa0761c95d70"
dependencies = [
"jobserver",
"libc",
"shlex",
]
@ -385,6 +456,18 @@ dependencies = [
"winapi",
]
[[package]]
name = "clircle"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8e87cbed5354f17bd8ca8821a097fb62599787fe8f611743fad7ee156a0a600"
dependencies = [
"cfg-if",
"libc",
"serde",
"winapi",
]
[[package]]
name = "clru"
version = "0.6.2"
@ -476,6 +559,7 @@ dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"unicode-width 0.1.14",
"windows-sys 0.52.0",
]
@ -499,6 +583,15 @@ dependencies = [
"tiny-keccak",
]
[[package]]
name = "content_inspector"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38"
dependencies = [
"memchr",
]
[[package]]
name = "convert_case"
version = "0.6.0"
@ -824,6 +917,17 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "etcetera"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943"
dependencies = [
"cfg-if",
"home",
"windows-sys 0.48.0",
]
[[package]]
name = "eyre"
version = "0.6.12"
@ -1026,6 +1130,39 @@ version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "git-version"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad568aa3db0fcbc81f2f116137f263d7304f512a1209b35b85150d3ef88ad19"
dependencies = [
"git-version-macro",
]
[[package]]
name = "git-version-macro"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
]
[[package]]
name = "git2"
version = "0.18.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "232e6a7bfe35766bf715e55a88b39a700596c0ccfd88cd3680b4cdb40d66ef70"
dependencies = [
"bitflags 2.6.0",
"libc",
"libgit2-sys",
"log",
"url",
]
[[package]]
name = "gix"
version = "0.66.0"
@ -1520,6 +1657,12 @@ dependencies = [
"thiserror",
]
[[package]]
name = "glob"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "globset"
version = "0.4.15"
@ -1533,6 +1676,20 @@ dependencies = [
"regex-syntax 0.8.5",
]
[[package]]
name = "grep-cli"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47f1288f0e06f279f84926fa4c17e3fcd2a22b357927a82f2777f7be26e4cec0"
dependencies = [
"bstr",
"globset",
"libc",
"log",
"termcolor",
"winapi-util",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
@ -1854,6 +2011,15 @@ dependencies = [
"jiff-tzdb",
]
[[package]]
name = "jobserver"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
dependencies = [
"libc",
]
[[package]]
name = "json5"
version = "0.4.1"
@ -1883,6 +2049,18 @@ version = "0.2.162"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
[[package]]
name = "libgit2-sys"
version = "0.16.2+1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8"
dependencies = [
"cc",
"libc",
"libz-sys",
"pkg-config",
]
[[package]]
name = "libloading"
version = "0.8.5"
@ -1904,6 +2082,18 @@ dependencies = [
"redox_syscall",
]
[[package]]
name = "libz-sys"
version = "1.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "linked-hash-map"
version = "0.5.6"
@ -2037,6 +2227,15 @@ dependencies = [
"winapi",
]
[[package]]
name = "nu-ansi-term"
version = "0.49.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c073d3c1930d0751774acf49e66653acecb416c3a54c6ec095a9b11caddb5a68"
dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "nucleo"
version = "0.5.0"
@ -2207,6 +2406,15 @@ version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "path_abs"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05ef02f6342ac01d8a93b65f96db53fe68a92a15f41144f97fb00a9e669633c3"
dependencies = [
"std_prelude",
]
[[package]]
name = "pathdiff"
version = "0.2.2"
@ -2474,6 +2682,15 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rgb"
version = "0.8.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a"
dependencies = [
"bytemuck",
]
[[package]]
name = "ron"
version = "0.8.1"
@ -2607,6 +2824,19 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_yaml"
version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
"indexmap",
"itoa",
"ryu",
"serde",
"unsafe-libyaml",
]
[[package]]
name = "sha1_smol"
version = "1.0.1"
@ -2633,6 +2863,18 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "shell-escape"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f"
[[package]]
name = "shell-words"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
[[package]]
name = "shlex"
version = "1.3.0"
@ -2742,6 +2984,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "std_prelude"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8207e78455ffdf55661170876f88daf85356e4edd54e0a3dbc79586ca1e50cbe"
[[package]]
name = "strip-ansi-escapes"
version = "0.2.0"
@ -2834,11 +3082,22 @@ dependencies = [
"yaml-rust",
]
[[package]]
name = "sys-info"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "television"
version = "0.1.13"
dependencies = [
"anyhow",
"bat",
"better-panic",
"clap",
"color-eyre",
@ -2900,6 +3159,15 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "termcolor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
dependencies = [
"winapi-util",
]
[[package]]
name = "terminal_size"
version = "0.4.0"
@ -3136,7 +3404,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [
"matchers",
"nu-ansi-term",
"nu-ansi-term 0.46.0",
"once_cell",
"regex",
"serde",
@ -3216,6 +3484,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
[[package]]
name = "unsafe-libyaml"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
[[package]]
name = "url"
version = "2.5.3"
@ -3260,6 +3534,12 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "vergen"
version = "9.0.1"
@ -3440,6 +3720,15 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "wild"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3131afc8c575281e1e80f36ed6a092aa502c08b18ed7524e86fbbb12bb410e1"
dependencies = [
"glob",
]
[[package]]
name = "winapi"
version = "0.3.9"

View File

@ -68,6 +68,7 @@ human-panic = "2.0.2"
pretty_assertions = "1.4.1"
termtree = "0.5.1"
copypasta = "0.10.1"
bat = "0.24.0"
[build-dependencies]

View File

@ -12,6 +12,7 @@ use tracing::{info, warn};
use crate::{
action::Action,
event::{convert_raw_event_to_key, Key},
previewers::{self, PreviewerConfig},
television::Mode,
};
@ -43,6 +44,40 @@ impl Default for UiConfig {
}
}
#[derive(Clone, Debug, Deserialize, Default)]
pub struct PreviewersConfig {
#[serde(default)]
pub basic: BasicPreviewerConfig,
#[serde(default)]
pub directory: DirectoryPreviewerConfig,
pub file: FilePreviewerConfig,
#[serde(default)]
pub env_var: EnvVarPreviewerConfig,
}
impl Into<PreviewerConfig> for PreviewersConfig {
fn into(self) -> PreviewerConfig {
PreviewerConfig::default().file(previewers::FilePreviewerConfig::new(
self.file.theme.clone(),
))
}
}
#[derive(Clone, Debug, Deserialize, Default)]
pub struct BasicPreviewerConfig {}
#[derive(Clone, Debug, Deserialize, Default)]
pub struct DirectoryPreviewerConfig {}
#[derive(Clone, Debug, Deserialize, Default)]
pub struct FilePreviewerConfig {
//pub max_file_size: u64,
pub theme: String,
}
#[derive(Clone, Debug, Deserialize, Default)]
pub struct EnvVarPreviewerConfig {}
#[allow(dead_code)]
#[derive(Clone, Debug, Default, Deserialize)]
pub struct Config {
@ -54,19 +89,25 @@ pub struct Config {
#[serde(default)]
pub styles: Styles,
pub ui: UiConfig,
#[serde(default)]
pub previewers: PreviewersConfig,
}
lazy_static! {
pub static ref PROJECT_NAME: String =
env!("CARGO_CRATE_NAME").to_uppercase().to_string();
pub static ref DATA_FOLDER: Option<PathBuf> =
env::var(format!("{}_DATA", PROJECT_NAME.clone()))
.ok()
.map(PathBuf::from);
// if `TELEVISION_DATA` is set, use that as the data directory
env::var_os(format!("{}_DATA", PROJECT_NAME.clone())).or_else(|| {
// otherwise, use the XDG data directory
env::var_os("XDG_DATA_HOME")
}).map(PathBuf::from).filter(|p| p.is_absolute());
pub static ref CONFIG_FOLDER: Option<PathBuf> =
env::var(format!("{}_CONFIG", PROJECT_NAME.clone()))
.ok()
.map(PathBuf::from);
// if `TELEVISION_CONFIG` is set, use that as the config directory
env::var_os(format!("{}_CONFIG", PROJECT_NAME.clone())).or_else(|| {
// otherwise, use the XDG config directory
env::var_os("XDG_CONFIG_HOME")
}).map(PathBuf::from).filter(|p| p.is_absolute());
}
const CONFIG_FILE_NAME: &str = "config.toml";

View File

@ -11,9 +11,13 @@ mod meta;
// previewer types
pub use basic::BasicPreviewer;
pub use basic::BasicPreviewerConfig;
pub use directory::DirectoryPreviewer;
pub use directory::DirectoryPreviewerConfig;
pub use env::EnvVarPreviewer;
pub use env::EnvVarPreviewerConfig;
pub use files::FilePreviewer;
pub use files::FilePreviewerConfig;
//use ratatui_image::protocol::StatefulProtocol;
use syntect::highlighting::Style;
@ -26,7 +30,7 @@ pub enum PreviewType {
Files,
}
#[derive(Clone)]
#[derive(Clone, Debug)]
pub enum PreviewContent {
Empty,
FileTooLarge,
@ -47,7 +51,7 @@ pub const FILE_TOO_LARGE_MSG: &str = "File too large";
/// # Fields
/// - `title`: The title of the preview.
/// - `content`: The content of the preview.
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct Preview {
pub title: String,
pub content: PreviewContent,
@ -80,6 +84,7 @@ impl Preview {
}
}
#[derive(Debug, Default)]
pub struct Previewer {
basic: BasicPreviewer,
directory: DirectoryPreviewer,
@ -87,19 +92,44 @@ pub struct Previewer {
env_var: EnvVarPreviewer,
}
impl Default for Previewer {
fn default() -> Self {
Previewer::new()
#[derive(Debug, Default)]
pub struct PreviewerConfig {
basic: BasicPreviewerConfig,
directory: DirectoryPreviewerConfig,
file: FilePreviewerConfig,
env_var: EnvVarPreviewerConfig,
}
impl PreviewerConfig {
pub fn basic(mut self, config: BasicPreviewerConfig) -> Self {
self.basic = config;
self
}
pub fn directory(mut self, config: DirectoryPreviewerConfig) -> Self {
self.directory = config;
self
}
pub fn file(mut self, config: FilePreviewerConfig) -> Self {
self.file = config;
self
}
pub fn env_var(mut self, config: EnvVarPreviewerConfig) -> Self {
self.env_var = config;
self
}
}
impl Previewer {
pub fn new() -> Self {
pub fn new(config: Option<PreviewerConfig>) -> Self {
let config = config.unwrap_or_default();
Previewer {
basic: BasicPreviewer::new(),
directory: DirectoryPreviewer::new(),
file: FilePreviewer::new(),
env_var: EnvVarPreviewer::new(),
basic: BasicPreviewer::new(Some(config.basic)),
directory: DirectoryPreviewer::new(Some(config.directory)),
file: FilePreviewer::new(Some(config.file)),
env_var: EnvVarPreviewer::new(Some(config.env_var)),
}
}
@ -111,4 +141,11 @@ impl Previewer {
PreviewType::Files => self.file.preview(entry).await,
}
}
pub fn set_config(&mut self, config: PreviewerConfig) {
self.basic = BasicPreviewer::new(Some(config.basic));
self.directory = DirectoryPreviewer::new(Some(config.directory));
self.file = FilePreviewer::new(Some(config.file));
self.env_var = EnvVarPreviewer::new(Some(config.env_var));
}
}

View File

@ -3,17 +3,19 @@ use std::sync::Arc;
use crate::entry::Entry;
use crate::previewers::{Preview, PreviewContent};
pub struct BasicPreviewer {}
impl Default for BasicPreviewer {
fn default() -> Self {
BasicPreviewer::new()
}
#[derive(Debug, Default)]
pub struct BasicPreviewer {
config: BasicPreviewerConfig,
}
#[derive(Debug, Default)]
pub struct BasicPreviewerConfig {}
impl BasicPreviewer {
pub fn new() -> Self {
BasicPreviewer {}
pub fn new(config: Option<BasicPreviewerConfig>) -> Self {
BasicPreviewer {
config: config.unwrap_or_default(),
}
}
pub fn preview(&self, entry: &Entry) -> Arc<Preview> {

View File

@ -44,6 +44,7 @@ use crate::previewers::Preview;
/// assert!(ring_set.contains(&3));
/// assert!(ring_set.contains(&4));
/// ```
#[derive(Debug)]
struct RingSet<T> {
ring_buffer: VecDeque<T>,
known_keys: HashSet<T>,
@ -107,6 +108,7 @@ const DEFAULT_PREVIEW_CACHE_SIZE: usize = 100;
/// A cache for previews.
/// The cache is implemented as an LRU cache with a fixed size.
#[derive(Debug)]
pub struct PreviewCache {
entries: HashMap<String, Arc<Preview>>,
ring_set: RingSet<String>,

View File

@ -11,20 +11,20 @@ use crate::previewers::cache::PreviewCache;
use crate::previewers::{meta, Preview, PreviewContent};
use crate::utils::files::walk_builder;
#[derive(Debug, Default)]
pub struct DirectoryPreviewer {
cache: Arc<Mutex<PreviewCache>>,
config: DirectoryPreviewerConfig,
}
impl Default for DirectoryPreviewer {
fn default() -> Self {
DirectoryPreviewer::new()
}
}
#[derive(Debug, Default)]
pub struct DirectoryPreviewerConfig {}
impl DirectoryPreviewer {
pub fn new() -> Self {
pub fn new(config: Option<DirectoryPreviewerConfig>) -> Self {
DirectoryPreviewer {
cache: Arc::new(Mutex::new(PreviewCache::default())),
config: config.unwrap_or_default(),
}
}

View File

@ -4,20 +4,20 @@ use std::sync::Arc;
use crate::entry;
use crate::previewers::{Preview, PreviewContent};
#[derive(Debug, Default)]
pub struct EnvVarPreviewer {
cache: HashMap<entry::Entry, Arc<Preview>>,
config: EnvVarPreviewerConfig,
}
impl Default for EnvVarPreviewer {
fn default() -> Self {
EnvVarPreviewer::new()
}
}
#[derive(Debug, Default)]
pub struct EnvVarPreviewerConfig {}
impl EnvVarPreviewer {
pub fn new() -> Self {
pub fn new(config: Option<EnvVarPreviewerConfig>) -> Self {
EnvVarPreviewer {
cache: HashMap::new(),
config: config.unwrap_or_default(),
}
}

View File

@ -22,8 +22,9 @@ use crate::utils::strings::{
preprocess_line, proportion_of_printable_ascii_characters,
PRINTABLE_ASCII_THRESHOLD,
};
use crate::utils::syntax;
use crate::utils::syntax::{self, load_highlighting_assets};
#[derive(Debug, Default)]
pub struct FilePreviewer {
cache: Arc<Mutex<PreviewCache>>,
pub syntax_set: Arc<SyntaxSet>,
@ -31,16 +32,29 @@ pub struct FilePreviewer {
//image_picker: Arc<Mutex<Picker>>,
}
impl Default for FilePreviewer {
fn default() -> Self {
FilePreviewer::new()
#[derive(Debug, Clone, Default)]
pub struct FilePreviewerConfig {
pub theme: String,
}
impl FilePreviewerConfig {
pub fn new(theme: String) -> Self {
FilePreviewerConfig { theme }
}
}
impl FilePreviewer {
pub fn new() -> Self {
let syntax_set = SyntaxSet::load_defaults_nonewlines();
pub fn new(config: Option<FilePreviewerConfig>) -> Self {
let hl_assets = load_highlighting_assets();
let syntax_set = hl_assets.get_syntax_set().unwrap().clone();
let theme = config.map_or_else(
|| {
let theme_set = ThemeSet::load_defaults();
theme_set.themes["base16-ocean.dark"].clone()
},
|c| hl_assets.get_theme(&c.theme).clone(),
);
//info!("getting image picker");
//let image_picker = get_image_picker();
//info!("got image picker");
@ -48,9 +62,7 @@ impl FilePreviewer {
FilePreviewer {
cache: Arc::new(Mutex::new(PreviewCache::default())),
syntax_set: Arc::new(syntax_set),
syntax_theme: Arc::new(
theme_set.themes["base16-ocean.dark"].clone(),
),
syntax_theme: Arc::new(theme),
//image_picker: Arc::new(Mutex::new(image_picker)),
}
}
@ -173,7 +185,9 @@ impl FilePreviewer {
let lines: Vec<String> = reader
.lines()
.map_while(Result::ok)
.map(|line| preprocess_line(&line))
// we need to add a newline here because sublime syntaxes expect one
// to be present at the end of each line
.map(|line| preprocess_line(&line) + "\n")
.collect();
match syntax::compute_highlights_for_path(

View File

@ -1,6 +1,7 @@
use crate::channels::remote_control::RemoteControl;
use crate::channels::{OnAir, UnitChannel};
use crate::picker::Picker;
use crate::previewers;
use crate::ui::layout::{Dimensions, Layout};
use crate::utils::strings::EMPTY_STRING;
use crate::{action::Action, config::Config};
@ -72,7 +73,7 @@ impl Television {
results_picker: Picker::default(),
rc_picker: Picker::default().inverted(),
results_area_height: 0,
previewer: Previewer::new(),
previewer: Previewer::default(),
preview_scroll: None,
preview_pane_height: 0,
current_preview_total_lines: 0,
@ -229,6 +230,11 @@ impl Television {
/// * `Result<()>` - An Ok result or an error.
pub fn register_config_handler(&mut self, config: Config) -> Result<()> {
self.config = config;
let previewer_config =
std::convert::Into::<previewers::PreviewerConfig>::into(
self.config.previewers.clone(),
);
self.previewer.set_config(previewer_config);
Ok(())
}

View File

@ -1,4 +1,5 @@
use std::path::Path;
use bat::assets::HighlightingAssets;
use std::path::{Path, PathBuf};
use syntect::easy::HighlightLines;
use syntect::highlighting::{Style, Theme};
use syntect::parsing::SyntaxSet;
@ -56,3 +57,49 @@ pub fn compute_highlights_for_line<'a>(
}
}
}
// Based on code from https://github.com/sharkdp/bat e981e974076a926a38f124b7d8746de2ca5f0a28
use directories::BaseDirs;
use lazy_static::lazy_static;
#[cfg(target_os = "macos")]
use std::env;
/// Wrapper for 'dirs' that treats MacOS more like Linux, by following the XDG specification.
/// This means that the `XDG_CACHE_HOME` and `XDG_CONFIG_HOME` environment variables are
/// checked first. The fallback directories are `~/.cache/bat` and `~/.config/bat`, respectively.
pub struct BatProjectDirs {
cache_dir: PathBuf,
}
impl BatProjectDirs {
fn new() -> Option<BatProjectDirs> {
#[cfg(target_os = "macos")]
let cache_dir_op = env::var_os("XDG_CACHE_HOME")
.map(PathBuf::from)
.filter(|p| p.is_absolute())
.or_else(|| BaseDirs::new().map(|d| d.home_dir().join(".cache")));
#[cfg(not(target_os = "macos"))]
let cache_dir_op = BaseDirs::new().map(|d| d.cache_dir().to_owned());
let cache_dir = cache_dir_op.map(|d| d.join("bat"))?;
Some(BatProjectDirs { cache_dir })
}
pub fn cache_dir(&self) -> &Path {
&self.cache_dir
}
}
lazy_static! {
pub static ref PROJECT_DIRS: BatProjectDirs = BatProjectDirs::new()
.unwrap_or_else(|| panic!("Could not get home directory"));
}
pub fn load_highlighting_assets() -> HighlightingAssets {
HighlightingAssets::from_cache(PROJECT_DIRS.cache_dir())
.unwrap_or_else(|_| bat::assets::HighlightingAssets::from_binary())
}