mirror of
https://github.com/sharkdp/bat.git
synced 2025-02-22 12:58:26 +00:00
Major restructuring of theme/syntax handling
This commit is contained in:
parent
b1b8addf7e
commit
06b7be7ee9
@ -29,7 +29,7 @@ fn main() {
|
|||||||
theme: "1337".into(),
|
theme: "1337".into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let assets = HighlightingAssets::new();
|
let assets = HighlightingAssets::from_binary();
|
||||||
|
|
||||||
Controller::new(&config, &assets).run().expect("no errors");
|
Controller::new(&config, &assets).run().expect("no errors");
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
use std::borrow::Cow;
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::Path;
|
||||||
|
|
||||||
use syntect::dumps::{dump_to_file, from_binary, from_reader};
|
use syntect::dumps::{dump_to_file, from_binary, from_reader};
|
||||||
use syntect::highlighting::{Theme, ThemeSet};
|
use syntect::highlighting::{Theme, ThemeSet};
|
||||||
use syntect::parsing::{SyntaxReference, SyntaxSet, SyntaxSetBuilder};
|
use syntect::parsing::{SyntaxReference, SyntaxSet, SyntaxSetBuilder};
|
||||||
|
|
||||||
use crate::dirs::PROJECT_DIRS;
|
|
||||||
|
|
||||||
use crate::errors::*;
|
use crate::errors::*;
|
||||||
use crate::inputfile::{InputFile, InputFileReader};
|
use crate::inputfile::{InputFile, InputFileReader};
|
||||||
use crate::syntax_mapping::SyntaxMapping;
|
use crate::syntax_mapping::SyntaxMapping;
|
||||||
@ -23,13 +20,7 @@ pub struct HighlightingAssets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HighlightingAssets {
|
impl HighlightingAssets {
|
||||||
pub fn new() -> Self {
|
pub fn from_files(source_dir: &Path, start_empty: bool) -> Result<Self> {
|
||||||
Self::from_cache().unwrap_or_else(|_| Self::from_binary())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_files(dir: Option<&Path>, start_empty: bool) -> Result<Self> {
|
|
||||||
let source_dir = dir.unwrap_or_else(|| PROJECT_DIRS.config_dir());
|
|
||||||
|
|
||||||
let mut theme_set = if start_empty {
|
let mut theme_set = if start_empty {
|
||||||
ThemeSet {
|
ThemeSet {
|
||||||
themes: BTreeMap::new(),
|
themes: BTreeMap::new(),
|
||||||
@ -72,12 +63,11 @@ impl HighlightingAssets {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_cache() -> Result<Self> {
|
pub fn from_cache(theme_set_path: &Path, syntax_set_path: &Path) -> Result<Self> {
|
||||||
let theme_set_path = theme_set_path();
|
let syntax_set_file = File::open(syntax_set_path).chain_err(|| {
|
||||||
let syntax_set_file = File::open(&syntax_set_path()).chain_err(|| {
|
|
||||||
format!(
|
format!(
|
||||||
"Could not load cached syntax set '{}'",
|
"Could not load cached syntax set '{}'",
|
||||||
syntax_set_path().to_string_lossy()
|
syntax_set_path.to_string_lossy()
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
let syntax_set: SyntaxSet = from_reader(BufReader::new(syntax_set_file))
|
let syntax_set: SyntaxSet = from_reader(BufReader::new(syntax_set_file))
|
||||||
@ -106,7 +96,7 @@ impl HighlightingAssets {
|
|||||||
from_binary(include_bytes!("../assets/themes.bin"))
|
from_binary(include_bytes!("../assets/themes.bin"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_binary() -> Self {
|
pub fn from_binary() -> Self {
|
||||||
let syntax_set = Self::get_integrated_syntaxset();
|
let syntax_set = Self::get_integrated_syntaxset();
|
||||||
let theme_set = Self::get_integrated_themeset();
|
let theme_set = Self::get_integrated_themeset();
|
||||||
|
|
||||||
@ -116,8 +106,7 @@ impl HighlightingAssets {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save(&self, dir: Option<&Path>) -> Result<()> {
|
pub fn save(&self, target_dir: &Path) -> Result<()> {
|
||||||
let target_dir = dir.unwrap_or_else(|| PROJECT_DIRS.cache_dir());
|
|
||||||
let _ = fs::create_dir_all(target_dir);
|
let _ = fs::create_dir_all(target_dir);
|
||||||
let theme_set_path = target_dir.join("themes.bin");
|
let theme_set_path = target_dir.join("themes.bin");
|
||||||
let syntax_set_path = target_dir.join("syntaxes.bin");
|
let syntax_set_path = target_dir.join("syntaxes.bin");
|
||||||
@ -204,29 +193,3 @@ impl HighlightingAssets {
|
|||||||
syntax.unwrap_or_else(|| self.syntax_set.find_syntax_plain_text())
|
syntax.unwrap_or_else(|| self.syntax_set.find_syntax_plain_text())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn theme_set_path() -> PathBuf {
|
|
||||||
PROJECT_DIRS.cache_dir().join("themes.bin")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn syntax_set_path() -> PathBuf {
|
|
||||||
PROJECT_DIRS.cache_dir().join("syntaxes.bin")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn config_dir() -> Cow<'static, str> {
|
|
||||||
PROJECT_DIRS.config_dir().to_string_lossy()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cache_dir() -> Cow<'static, str> {
|
|
||||||
PROJECT_DIRS.cache_dir().to_string_lossy()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clear_assets() {
|
|
||||||
print!("Clearing theme set cache ... ");
|
|
||||||
fs::remove_file(theme_set_path()).ok();
|
|
||||||
println!("okay");
|
|
||||||
|
|
||||||
print!("Clearing syntax set cache ... ");
|
|
||||||
fs::remove_file(syntax_set_path()).ok();
|
|
||||||
println!("okay");
|
|
||||||
}
|
|
||||||
|
37
src/bin/bat/assets.rs
Normal file
37
src/bin/bat/assets.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
|
use std::fs;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use crate::directories::PROJECT_DIRS;
|
||||||
|
|
||||||
|
use bat::assets::HighlightingAssets;
|
||||||
|
|
||||||
|
fn theme_set_path() -> PathBuf {
|
||||||
|
PROJECT_DIRS.cache_dir().join("themes.bin")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn syntax_set_path() -> PathBuf {
|
||||||
|
PROJECT_DIRS.cache_dir().join("syntaxes.bin")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn config_dir() -> Cow<'static, str> {
|
||||||
|
PROJECT_DIRS.config_dir().to_string_lossy()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cache_dir() -> Cow<'static, str> {
|
||||||
|
PROJECT_DIRS.cache_dir().to_string_lossy()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_assets() {
|
||||||
|
print!("Clearing theme set cache ... ");
|
||||||
|
fs::remove_file(theme_set_path()).ok();
|
||||||
|
println!("okay");
|
||||||
|
|
||||||
|
print!("Clearing syntax set cache ... ");
|
||||||
|
fs::remove_file(syntax_set_path()).ok();
|
||||||
|
println!("okay");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn assets_from_cache_or_binary() -> HighlightingAssets {
|
||||||
|
HighlightingAssets::from_cache(&theme_set_path(), &syntax_set_path()).unwrap_or(HighlightingAssets::from_binary())
|
||||||
|
}
|
@ -5,7 +5,7 @@ use std::path::PathBuf;
|
|||||||
|
|
||||||
use shell_words;
|
use shell_words;
|
||||||
|
|
||||||
use bat::dirs::PROJECT_DIRS;
|
use crate::directories::PROJECT_DIRS;
|
||||||
|
|
||||||
pub fn config_file() -> PathBuf {
|
pub fn config_file() -> PathBuf {
|
||||||
env::var("BAT_CONFIG_PATH")
|
env::var("BAT_CONFIG_PATH")
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
use crate::dirs_rs;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use dirs;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
/// Wrapper for 'dirs' that treats MacOS more like Linux, by following the XDG specification.
|
/// 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
|
/// 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.
|
/// checked first. The fallback directories are `~/.cache/bat` and `~/.config/bat`, respectively.
|
||||||
@ -18,10 +20,10 @@ impl BatProjectDirs {
|
|||||||
let config_dir_op = env::var_os("XDG_CONFIG_HOME")
|
let config_dir_op = env::var_os("XDG_CONFIG_HOME")
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.filter(|p| p.is_absolute())
|
.filter(|p| p.is_absolute())
|
||||||
.or_else(|| dirs_rs::home_dir().map(|d| d.join(".config")));
|
.or_else(|| dirs::home_dir().map(|d| d.join(".config")));
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
let config_dir_op = dirs_rs::config_dir();
|
let config_dir_op = dirs::config_dir();
|
||||||
|
|
||||||
let config_dir = config_dir_op.map(|d| d.join("bat"))?;
|
let config_dir = config_dir_op.map(|d| d.join("bat"))?;
|
||||||
|
|
||||||
@ -42,10 +44,10 @@ impl BatProjectDirs {
|
|||||||
let cache_dir_op = env::var_os("XDG_CACHE_HOME")
|
let cache_dir_op = env::var_os("XDG_CACHE_HOME")
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.filter(|p| p.is_absolute())
|
.filter(|p| p.is_absolute())
|
||||||
.or_else(|| dirs_rs::home_dir().map(|d| d.join(".cache")));
|
.or_else(|| dirs::home_dir().map(|d| d.join(".cache")));
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
let cache_dir_op = dirs_rs::cache_dir();
|
let cache_dir_op = dirs::cache_dir();
|
||||||
|
|
||||||
cache_dir_op.map(|d| d.join("bat"))
|
cache_dir_op.map(|d| d.join("bat"))
|
||||||
}
|
}
|
@ -4,9 +4,13 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
|
|
||||||
|
extern crate dirs as dirs_rs;
|
||||||
|
|
||||||
mod app;
|
mod app;
|
||||||
mod clap_app;
|
mod clap_app;
|
||||||
mod config;
|
mod config;
|
||||||
|
mod directories;
|
||||||
|
mod assets;
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
@ -19,10 +23,12 @@ use ansi_term::Colour::Green;
|
|||||||
use ansi_term::Style;
|
use ansi_term::Style;
|
||||||
|
|
||||||
use crate::{app::App, config::config_file};
|
use crate::{app::App, config::config_file};
|
||||||
|
use directories::PROJECT_DIRS;
|
||||||
|
use assets::{cache_dir, clear_assets, config_dir, assets_from_cache_or_binary};
|
||||||
use bat::controller::Controller;
|
use bat::controller::Controller;
|
||||||
|
|
||||||
use bat::{
|
use bat::{
|
||||||
assets::{cache_dir, clear_assets, config_dir, HighlightingAssets},
|
assets::HighlightingAssets,
|
||||||
errors::*,
|
errors::*,
|
||||||
inputfile::InputFile,
|
inputfile::InputFile,
|
||||||
style::{OutputComponent, OutputComponents},
|
style::{OutputComponent, OutputComponents},
|
||||||
@ -31,8 +37,8 @@ use bat::{
|
|||||||
|
|
||||||
fn run_cache_subcommand(matches: &clap::ArgMatches) -> Result<()> {
|
fn run_cache_subcommand(matches: &clap::ArgMatches) -> Result<()> {
|
||||||
if matches.is_present("build") {
|
if matches.is_present("build") {
|
||||||
let source_dir = matches.value_of("source").map(Path::new);
|
let source_dir = matches.value_of("source").map(Path::new).unwrap_or_else(|| PROJECT_DIRS.config_dir());
|
||||||
let target_dir = matches.value_of("target").map(Path::new);
|
let target_dir = matches.value_of("target").map(Path::new).unwrap_or_else(|| PROJECT_DIRS.cache_dir());
|
||||||
|
|
||||||
let blank = matches.is_present("blank");
|
let blank = matches.is_present("blank");
|
||||||
|
|
||||||
@ -46,7 +52,7 @@ fn run_cache_subcommand(matches: &clap::ArgMatches) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_languages(config: &Config) -> Result<()> {
|
pub fn list_languages(config: &Config) -> Result<()> {
|
||||||
let assets = HighlightingAssets::new();
|
let assets = assets_from_cache_or_binary();
|
||||||
let mut languages = assets
|
let mut languages = assets
|
||||||
.syntax_set
|
.syntax_set
|
||||||
.syntaxes()
|
.syntaxes()
|
||||||
@ -109,7 +115,7 @@ pub fn list_languages(config: &Config) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_themes(cfg: &Config) -> Result<()> {
|
pub fn list_themes(cfg: &Config) -> Result<()> {
|
||||||
let assets = HighlightingAssets::new();
|
let assets = assets_from_cache_or_binary();
|
||||||
let themes = &assets.theme_set.themes;
|
let themes = &assets.theme_set.themes;
|
||||||
let mut config = cfg.clone();
|
let mut config = cfg.clone();
|
||||||
let mut style = HashSet::new();
|
let mut style = HashSet::new();
|
||||||
@ -141,7 +147,7 @@ pub fn list_themes(cfg: &Config) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run_controller(config: &Config) -> Result<bool> {
|
fn run_controller(config: &Config) -> Result<bool> {
|
||||||
let assets = HighlightingAssets::new();
|
let assets = assets_from_cache_or_binary();
|
||||||
let controller = Controller::new(&config, &assets);
|
let controller = Controller::new(&config, &assets);
|
||||||
controller.run()
|
controller.run()
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,6 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate error_chain;
|
extern crate error_chain;
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate lazy_static;
|
|
||||||
|
|
||||||
extern crate ansi_term;
|
extern crate ansi_term;
|
||||||
extern crate atty;
|
extern crate atty;
|
||||||
extern crate console;
|
extern crate console;
|
||||||
@ -22,7 +19,6 @@ pub mod assets;
|
|||||||
pub mod controller;
|
pub mod controller;
|
||||||
mod decorations;
|
mod decorations;
|
||||||
mod diff;
|
mod diff;
|
||||||
pub mod dirs;
|
|
||||||
pub mod inputfile;
|
pub mod inputfile;
|
||||||
mod less;
|
mod less;
|
||||||
pub mod line_range;
|
pub mod line_range;
|
||||||
|
@ -6,20 +6,22 @@ pub struct LineRange {
|
|||||||
pub upper: usize,
|
pub upper: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LineRange {
|
impl Default for LineRange {
|
||||||
pub fn from(range_raw: &str) -> Result<LineRange> {
|
fn default() -> LineRange {
|
||||||
LineRange::parse_range(range_raw)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new() -> LineRange {
|
|
||||||
LineRange {
|
LineRange {
|
||||||
lower: usize::min_value(),
|
lower: usize::min_value(),
|
||||||
upper: usize::max_value(),
|
upper: usize::max_value(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LineRange {
|
||||||
|
pub fn from(range_raw: &str) -> Result<LineRange> {
|
||||||
|
LineRange::parse_range(range_raw)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse_range(range_raw: &str) -> Result<LineRange> {
|
pub fn parse_range(range_raw: &str) -> Result<LineRange> {
|
||||||
let mut new_range = LineRange::new();
|
let mut new_range = LineRange::default();
|
||||||
|
|
||||||
if range_raw.bytes().nth(0).ok_or("Empty line range")? == b':' {
|
if range_raw.bytes().nth(0).ok_or("Empty line range")? == b':' {
|
||||||
new_range.upper = range_raw[1..].parse()?;
|
new_range.upper = range_raw[1..].parse()?;
|
||||||
@ -103,12 +105,18 @@ pub enum RangeCheckResult {
|
|||||||
AfterLastRange,
|
AfterLastRange,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct LineRanges {
|
pub struct LineRanges {
|
||||||
ranges: Vec<LineRange>,
|
ranges: Vec<LineRange>,
|
||||||
largest_upper_bound: usize,
|
largest_upper_bound: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for LineRanges {
|
||||||
|
fn default() -> Self {
|
||||||
|
LineRanges::from(vec![LineRange { lower: 0, upper: 0 }])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl LineRanges {
|
impl LineRanges {
|
||||||
pub fn from(ranges: Vec<LineRange>) -> LineRanges {
|
pub fn from(ranges: Vec<LineRange>) -> LineRanges {
|
||||||
let largest_upper_bound = ranges
|
let largest_upper_bound = ranges
|
||||||
|
@ -19,7 +19,7 @@ fn no_duplicate_extensions() {
|
|||||||
"sass",
|
"sass",
|
||||||
];
|
];
|
||||||
|
|
||||||
let assets = HighlightingAssets::new();
|
let assets = HighlightingAssets::from_binary();
|
||||||
|
|
||||||
let mut extensions = HashSet::new();
|
let mut extensions = HashSet::new();
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ struct SyntaxDetectionTest {
|
|||||||
impl SyntaxDetectionTest {
|
impl SyntaxDetectionTest {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
SyntaxDetectionTest {
|
SyntaxDetectionTest {
|
||||||
assets: HighlightingAssets::new(),
|
assets: HighlightingAssets::from_binary(),
|
||||||
syntax_mapping: SyntaxMapping::new(),
|
syntax_mapping: SyntaxMapping::new(),
|
||||||
temp_dir: TempDir::new("bat_syntax_detection_tests")
|
temp_dir: TempDir::new("bat_syntax_detection_tests")
|
||||||
.expect("creation of temporary directory"),
|
.expect("creation of temporary directory"),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user