mirror of
https://github.com/dtolnay/cargo-expand.git
synced 2025-04-03 12:57:38 +03:00
Merge pull request #238 from dtolnay/assets
Load custom bat theme assets
This commit is contained in:
commit
c396c12b61
7 changed files with 117 additions and 5 deletions
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
|
@ -77,5 +77,6 @@ jobs:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
- uses: dtolnay/install@cargo-outdated
|
- uses: dtolnay/install@cargo-outdated
|
||||||
|
- run: cargo tree --package bat --depth 0 | grep "^bat v$(cat src/bat.version)$"
|
||||||
- run: cargo update
|
- run: cargo update
|
||||||
- run: cargo outdated --workspace --exit-code 1
|
- run: cargo outdated --workspace --exit-code 1
|
||||||
|
|
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -184,10 +184,13 @@ dependencies = [
|
||||||
"cargo-subcommand-metadata",
|
"cargo-subcommand-metadata",
|
||||||
"clap",
|
"clap",
|
||||||
"console",
|
"console",
|
||||||
|
"etcetera",
|
||||||
"fs-err",
|
"fs-err",
|
||||||
|
"home",
|
||||||
"prettyplease",
|
"prettyplease",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
"semver",
|
||||||
"serde",
|
"serde",
|
||||||
"shlex",
|
"shlex",
|
||||||
"syn",
|
"syn",
|
||||||
|
@ -343,6 +346,17 @@ dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"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]]
|
[[package]]
|
||||||
name = "fancy-regex"
|
name = "fancy-regex"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
|
|
|
@ -21,10 +21,13 @@ bat = { version = "0.24", default-features = false, features = ["paging", "regex
|
||||||
cargo-subcommand-metadata = "0.1"
|
cargo-subcommand-metadata = "0.1"
|
||||||
clap = { version = "4", features = ["deprecated", "derive"] }
|
clap = { version = "4", features = ["deprecated", "derive"] }
|
||||||
console = "0.15"
|
console = "0.15"
|
||||||
|
etcetera = "0.8"
|
||||||
fs-err = "3"
|
fs-err = "3"
|
||||||
|
home = "0.5"
|
||||||
prettyplease = { version = "0.2.25", features = ["verbatim"] }
|
prettyplease = { version = "0.2.25", features = ["verbatim"] }
|
||||||
proc-macro2 = "1.0.80"
|
proc-macro2 = "1.0.80"
|
||||||
quote = { version = "1.0.35", default-features = false }
|
quote = { version = "1.0.35", default-features = false }
|
||||||
|
semver = "1"
|
||||||
serde = { version = "1.0.183", features = ["derive"] }
|
serde = { version = "1.0.183", features = ["derive"] }
|
||||||
shlex = "1.3"
|
shlex = "1.3"
|
||||||
syn = { version = "2.0.85", default-features = false, features = ["clone-impls", "fold", "full", "parsing", "printing", "visit-mut"] }
|
syn = { version = "2.0.85", default-features = false, features = ["clone-impls", "fold", "full", "parsing", "printing", "visit-mut"] }
|
||||||
|
|
26
src/assets.rs
Normal file
26
src/assets.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
use crate::error::Result;
|
||||||
|
use etcetera::BaseStrategy as _;
|
||||||
|
use std::env;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::str;
|
||||||
|
|
||||||
|
pub const BAT_VERSION: &str = {
|
||||||
|
let mut bytes = include_str!("bat.version").as_bytes();
|
||||||
|
while let [rest @ .., b'\n' | b'\r'] = bytes {
|
||||||
|
bytes = rest;
|
||||||
|
}
|
||||||
|
if let Ok(version) = str::from_utf8(bytes) {
|
||||||
|
version
|
||||||
|
} else {
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn cache_dir() -> Result<PathBuf> {
|
||||||
|
if let Some(cache_dir) = env::var_os("BAT_CACHE_PATH") {
|
||||||
|
return Ok(PathBuf::from(cache_dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
let basedirs = etcetera::choose_base_strategy()?;
|
||||||
|
Ok(basedirs.cache_dir().join("bat"))
|
||||||
|
}
|
1
src/bat.version
Normal file
1
src/bat.version
Normal file
|
@ -0,0 +1 @@
|
||||||
|
0.24.0
|
18
src/error.rs
18
src/error.rs
|
@ -8,6 +8,8 @@ pub enum Error {
|
||||||
TomlSer(toml::ser::Error),
|
TomlSer(toml::ser::Error),
|
||||||
TomlDe(toml::de::Error),
|
TomlDe(toml::de::Error),
|
||||||
Quote(shlex::QuoteError),
|
Quote(shlex::QuoteError),
|
||||||
|
HomeDir(etcetera::HomeDirError),
|
||||||
|
Bat(bat::error::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
@ -36,6 +38,18 @@ impl From<shlex::QuoteError> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<etcetera::HomeDirError> for Error {
|
||||||
|
fn from(error: etcetera::HomeDirError) -> Self {
|
||||||
|
Error::HomeDir(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<bat::error::Error> for Error {
|
||||||
|
fn from(error: bat::error::Error) -> Self {
|
||||||
|
Error::Bat(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for Error {
|
impl Display for Error {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
@ -43,6 +57,8 @@ impl Display for Error {
|
||||||
Error::TomlSer(e) => e.fmt(formatter),
|
Error::TomlSer(e) => e.fmt(formatter),
|
||||||
Error::TomlDe(e) => e.fmt(formatter),
|
Error::TomlDe(e) => e.fmt(formatter),
|
||||||
Error::Quote(e) => e.fmt(formatter),
|
Error::Quote(e) => e.fmt(formatter),
|
||||||
|
Error::HomeDir(e) => e.fmt(formatter),
|
||||||
|
Error::Bat(e) => e.fmt(formatter),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,6 +70,8 @@ impl StdError for Error {
|
||||||
Error::TomlSer(e) => e.source(),
|
Error::TomlSer(e) => e.source(),
|
||||||
Error::TomlDe(e) => e.source(),
|
Error::TomlDe(e) => e.source(),
|
||||||
Error::Quote(e) => e.source(),
|
Error::Quote(e) => e.source(),
|
||||||
|
Error::HomeDir(e) => e.source(),
|
||||||
|
Error::Bat(e) => e.source(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
59
src/main.rs
59
src/main.rs
|
@ -16,6 +16,7 @@
|
||||||
clippy::uninlined_format_args,
|
clippy::uninlined_format_args,
|
||||||
)]
|
)]
|
||||||
|
|
||||||
|
mod assets;
|
||||||
mod cmd;
|
mod cmd;
|
||||||
mod config;
|
mod config;
|
||||||
mod edit;
|
mod edit;
|
||||||
|
@ -33,6 +34,7 @@ use crate::opts::{Coloring, Expand, Subcommand};
|
||||||
use crate::unparse::unparse_maximal;
|
use crate::unparse::unparse_maximal;
|
||||||
use crate::version::Version;
|
use crate::version::Version;
|
||||||
use bat::assets::HighlightingAssets;
|
use bat::assets::HighlightingAssets;
|
||||||
|
use bat::assets_metadata::AssetsMetadata;
|
||||||
use bat::config::VisibleLines;
|
use bat::config::VisibleLines;
|
||||||
use bat::line_range::{HighlightedLineRanges, LineRanges};
|
use bat::line_range::{HighlightedLineRanges, LineRanges};
|
||||||
use bat::style::StyleComponents;
|
use bat::style::StyleComponents;
|
||||||
|
@ -138,9 +140,7 @@ fn do_cargo_expand() -> Result<i32> {
|
||||||
let config = config::deserialize();
|
let config = config::deserialize();
|
||||||
|
|
||||||
if args.themes {
|
if args.themes {
|
||||||
for theme in HighlightingAssets::from_binary().themes() {
|
print_themes()?;
|
||||||
let _ = writeln!(io::stdout(), "{}", theme);
|
|
||||||
}
|
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,6 +290,20 @@ fn do_cargo_expand() -> Result<i32> {
|
||||||
};
|
};
|
||||||
let _ = writeln!(io::stderr());
|
let _ = writeln!(io::stderr());
|
||||||
if do_color {
|
if do_color {
|
||||||
|
let mut assets = HighlightingAssets::from_binary();
|
||||||
|
if let Some(requested_theme) = &theme {
|
||||||
|
if !assets
|
||||||
|
.themes()
|
||||||
|
.any(|supported_theme| supported_theme == requested_theme)
|
||||||
|
{
|
||||||
|
let cache_dir = assets::cache_dir()?;
|
||||||
|
if let Some(metadata) = AssetsMetadata::load_from_folder(&cache_dir)? {
|
||||||
|
if metadata.is_compatible_with(assets::BAT_VERSION) {
|
||||||
|
assets = HighlightingAssets::from_cache(&cache_dir)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
let config = bat::config::Config {
|
let config = bat::config::Config {
|
||||||
language: Some("rust"),
|
language: Some("rust"),
|
||||||
show_nonprintable: false,
|
show_nonprintable: false,
|
||||||
|
@ -310,10 +324,8 @@ fn do_cargo_expand() -> Result<i32> {
|
||||||
pager: None,
|
pager: None,
|
||||||
use_italic_text: false,
|
use_italic_text: false,
|
||||||
highlighted_lines: HighlightedLineRanges(LineRanges::none()),
|
highlighted_lines: HighlightedLineRanges(LineRanges::none()),
|
||||||
use_custom_assets: false,
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let assets = HighlightingAssets::from_binary();
|
|
||||||
let controller = bat::controller::Controller::new(&config, &assets);
|
let controller = bat::controller::Controller::new(&config, &assets);
|
||||||
let inputs = vec![bat::input::Input::from_reader(Box::new(content.as_bytes()))];
|
let inputs = vec![bat::input::Input::from_reader(Box::new(content.as_bytes()))];
|
||||||
// Ignore any errors.
|
// Ignore any errors.
|
||||||
|
@ -657,3 +669,40 @@ fn get_color(args: &Expand, config: &Config) -> Coloring {
|
||||||
|
|
||||||
Coloring::Auto // default
|
Coloring::Auto // default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_themes() -> Result<()> {
|
||||||
|
let mut cache_dir = assets::cache_dir()?;
|
||||||
|
let metadata = AssetsMetadata::load_from_folder(&cache_dir)?;
|
||||||
|
let compatible = metadata
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |m| m.is_compatible_with(assets::BAT_VERSION));
|
||||||
|
let assets = if compatible {
|
||||||
|
HighlightingAssets::from_cache(&cache_dir)?
|
||||||
|
} else {
|
||||||
|
HighlightingAssets::from_binary()
|
||||||
|
};
|
||||||
|
|
||||||
|
for theme in assets.themes() {
|
||||||
|
let _ = writeln!(io::stdout(), "{}", theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
if metadata.is_some() && !compatible {
|
||||||
|
if let Some(home_dir) = home::home_dir() {
|
||||||
|
if let Ok(relative) = cache_dir.strip_prefix(home_dir) {
|
||||||
|
cache_dir = Path::new("~").join(relative);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let bat_version = semver::Version::parse(assets::BAT_VERSION).unwrap();
|
||||||
|
let _ = writeln!(
|
||||||
|
io::stderr(),
|
||||||
|
"\nThere may be other themes in {cache_dir} but they are not \
|
||||||
|
compatible with the version of bat built into cargo-expand. Run \
|
||||||
|
`bat cache --build` with bat v{major}.{minor} to update the cache.",
|
||||||
|
cache_dir = cache_dir.display(),
|
||||||
|
major = bat_version.major,
|
||||||
|
minor = bat_version.minor,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue