Merge pull request #18 from teohhanhui/riir
Tie fore-back to distro ascii instead of config
This commit is contained in:
commit
85a85ad4d3
3 changed files with 115 additions and 36 deletions
|
@ -9,7 +9,7 @@ use hyfetch::cli_options::options;
|
|||
use hyfetch::models::Config;
|
||||
#[cfg(windows)]
|
||||
use hyfetch::neofetch_util::ensure_git_bash;
|
||||
use hyfetch::neofetch_util::{self, get_distro_ascii};
|
||||
use hyfetch::neofetch_util::{self, get_distro_ascii, ColorAlignment};
|
||||
use hyfetch::presets::AssignLightness;
|
||||
use hyfetch::utils::get_cache_path;
|
||||
use tracing::debug;
|
||||
|
@ -33,10 +33,8 @@ fn main() -> Result<()> {
|
|||
ensure_git_bash().context("failed to find git bash")?;
|
||||
|
||||
if options.test_print {
|
||||
println!(
|
||||
"{}",
|
||||
get_distro_ascii(distro).context("failed to get distro ascii")?
|
||||
);
|
||||
let (asc, _) = get_distro_ascii(distro).context("failed to get distro ascii")?;
|
||||
println!("{asc}");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
@ -94,13 +92,28 @@ fn main() -> Result<()> {
|
|||
};
|
||||
debug!(?color_profile, "lightened color profile");
|
||||
|
||||
let asc = if let Some(path) = options.ascii_file {
|
||||
fs::read_to_string(&path).with_context(|| format!("failed to read ascii from {path:?}"))?
|
||||
let (asc, fore_back) = if let Some(path) = options.ascii_file {
|
||||
(
|
||||
fs::read_to_string(&path)
|
||||
.with_context(|| format!("failed to read ascii from {path:?}"))?,
|
||||
None,
|
||||
)
|
||||
} else {
|
||||
get_distro_ascii(distro).context("failed to get distro ascii")?
|
||||
};
|
||||
let asc = config
|
||||
.color_align
|
||||
let color_align = if fore_back.is_some() {
|
||||
match config.color_align {
|
||||
ca @ ColorAlignment::Horizontal { .. } | ca @ ColorAlignment::Vertical { .. } => {
|
||||
ca.with_fore_back(fore_back).context(
|
||||
"failed to create color alignment with foreground-background configuration",
|
||||
)?
|
||||
},
|
||||
ca @ ColorAlignment::Custom { .. } => ca,
|
||||
}
|
||||
} else {
|
||||
config.color_align
|
||||
};
|
||||
let asc = color_align
|
||||
.recolor_ascii(asc, color_profile, color_mode, config.light_dark)
|
||||
.context("failed to recolor ascii")?;
|
||||
neofetch_util::run(asc, backend, args).context("failed to run")?;
|
||||
|
|
|
@ -27,15 +27,19 @@ use crate::types::{AnsiMode, Backend, LightDark};
|
|||
const NEOFETCH_COLOR_PATTERNS: [&str; 6] = ["${c1}", "${c2}", "${c3}", "${c4}", "${c5}", "${c6}"];
|
||||
static NEOFETCH_COLORS_AC: OnceLock<AhoCorasick> = OnceLock::new();
|
||||
|
||||
type ForeBackColorPair = (NeofetchAsciiIndexedColor, NeofetchAsciiIndexedColor);
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Debug, Deserialize, Serialize)]
|
||||
#[serde(tag = "mode")]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum ColorAlignment {
|
||||
Horizontal {
|
||||
fore_back: Option<(NeofetchAsciiIndexedColor, NeofetchAsciiIndexedColor)>,
|
||||
#[serde(skip)]
|
||||
fore_back: Option<ForeBackColorPair>,
|
||||
},
|
||||
Vertical {
|
||||
fore_back: Option<(NeofetchAsciiIndexedColor, NeofetchAsciiIndexedColor)>,
|
||||
#[serde(skip)]
|
||||
fore_back: Option<ForeBackColorPair>,
|
||||
},
|
||||
Custom {
|
||||
#[serde(rename = "custom_colors")]
|
||||
|
@ -45,8 +49,35 @@ pub enum ColorAlignment {
|
|||
}
|
||||
|
||||
impl ColorAlignment {
|
||||
/// Creates a new color alignment, with the specified foreground-background
|
||||
/// configuration.
|
||||
pub fn with_fore_back(&self, fore_back: Option<ForeBackColorPair>) -> Result<Self> {
|
||||
match self {
|
||||
Self::Horizontal { .. } => Ok(Self::Horizontal { fore_back }),
|
||||
Self::Vertical { .. } => {
|
||||
if fore_back.is_some() {
|
||||
debug!(
|
||||
"foreground-background configuration not implemented for vertical color \
|
||||
alignment; ignoring"
|
||||
);
|
||||
}
|
||||
Ok(Self::Vertical { fore_back: None })
|
||||
},
|
||||
Self::Custom { colors } => {
|
||||
if fore_back.is_some() {
|
||||
return Err(anyhow!(
|
||||
"foreground-background configuration not supported for custom colors"
|
||||
));
|
||||
}
|
||||
Ok(Self::Custom {
|
||||
colors: colors.clone(),
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Uses the color alignment to recolor an ascii art.
|
||||
#[tracing::instrument(level = "debug")]
|
||||
#[tracing::instrument(level = "debug", skip(asc))]
|
||||
pub fn recolor_ascii(
|
||||
&self,
|
||||
asc: String,
|
||||
|
@ -54,19 +85,20 @@ impl ColorAlignment {
|
|||
color_mode: AnsiMode,
|
||||
term: LightDark,
|
||||
) -> Result<String> {
|
||||
let asc = fill_starting(asc).context("failed to fill in starting neofetch color codes")?;
|
||||
|
||||
let reset = color("&~&*", color_mode).expect("color reset should not be invalid");
|
||||
|
||||
let asc = match self {
|
||||
Self::Horizontal {
|
||||
&Self::Horizontal {
|
||||
fore_back: Some((fore, back)),
|
||||
}
|
||||
| Self::Vertical {
|
||||
| &Self::Vertical {
|
||||
fore_back: Some((fore, back)),
|
||||
} => {
|
||||
let fore: u8 = (*fore).into();
|
||||
let back: u8 = (*back).into();
|
||||
let fore: u8 = fore.into();
|
||||
let back: u8 = back.into();
|
||||
|
||||
let asc = fill_starting(asc)
|
||||
.context("failed to fill in starting neofetch color codes")?;
|
||||
|
||||
// Replace foreground colors
|
||||
let asc = asc.replace(
|
||||
|
@ -191,6 +223,9 @@ impl ColorAlignment {
|
|||
Self::Custom {
|
||||
colors: custom_colors,
|
||||
} => {
|
||||
let asc = fill_starting(asc)
|
||||
.context("failed to fill in starting neofetch color codes")?;
|
||||
|
||||
let ColorProfile { colors } = color_profile.unique_colors();
|
||||
|
||||
// Apply colors
|
||||
|
@ -215,6 +250,39 @@ impl ColorAlignment {
|
|||
|
||||
Ok(asc)
|
||||
}
|
||||
|
||||
/// Gets recommended foreground-background configuration for distro, or
|
||||
/// `None` if the distro ascii is not suitable for fore-back configuration.
|
||||
pub fn fore_back(distro: Distro) -> Option<ForeBackColorPair> {
|
||||
match distro {
|
||||
Distro::Anarchy
|
||||
| Distro::ArchStrike
|
||||
| Distro::Astra_Linux
|
||||
| Distro::Chapeau
|
||||
| Distro::Fedora
|
||||
| Distro::GalliumOS
|
||||
| Distro::KrassOS
|
||||
| Distro::Kubuntu
|
||||
| Distro::Lubuntu
|
||||
| Distro::openEuler
|
||||
| Distro::Peppermint
|
||||
| Distro::Pop__OS
|
||||
| Distro::Ubuntu_Cinnamon
|
||||
| Distro::Ubuntu_Kylin
|
||||
| Distro::Ubuntu_MATE
|
||||
| Distro::Ubuntu_old
|
||||
| Distro::Ubuntu_Studio
|
||||
| Distro::Ubuntu_Sway
|
||||
| Distro::Ultramarine_Linux
|
||||
| Distro::Univention
|
||||
| Distro::Vanilla
|
||||
| Distro::Xubuntu => Some((2u8.try_into().unwrap(), 1u8.try_into().unwrap())),
|
||||
|
||||
Distro::Antergos => Some((1u8.try_into().unwrap(), 2u8.try_into().unwrap())),
|
||||
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the absolute path of the neofetch command.
|
||||
|
@ -318,7 +386,7 @@ pub fn ensure_git_bash() -> Result<PathBuf> {
|
|||
/// Gets the distro ascii of the current distro. Or if distro is specified, get
|
||||
/// the specific distro's ascii art instead.
|
||||
#[tracing::instrument(level = "debug")]
|
||||
pub fn get_distro_ascii<S>(distro: Option<S>) -> Result<String>
|
||||
pub fn get_distro_ascii<S>(distro: Option<S>) -> Result<(String, Option<ForeBackColorPair>)>
|
||||
where
|
||||
S: AsRef<str> + fmt::Debug,
|
||||
{
|
||||
|
@ -333,7 +401,10 @@ where
|
|||
|
||||
// Try new codegen-based detection method
|
||||
if let Some(distro) = Distro::detect(&distro) {
|
||||
return Ok(normalize_ascii(distro.ascii_art()));
|
||||
return Ok((
|
||||
normalize_ascii(distro.ascii_art()),
|
||||
ColorAlignment::fore_back(distro),
|
||||
));
|
||||
}
|
||||
|
||||
debug!(%distro, "could not find a match for distro; falling back to neofetch");
|
||||
|
@ -346,10 +417,10 @@ where
|
|||
// printf
|
||||
let asc = asc.replace(r"\\", r"\");
|
||||
|
||||
Ok(normalize_ascii(asc))
|
||||
Ok((normalize_ascii(asc), None))
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug")]
|
||||
#[tracing::instrument(level = "debug", skip(asc))]
|
||||
pub fn run(asc: String, backend: Backend, args: Option<&Vec<String>>) -> Result<()> {
|
||||
match backend {
|
||||
Backend::Neofetch => {
|
||||
|
@ -432,7 +503,7 @@ where
|
|||
let mut matches = ac.find_iter(line).peekable();
|
||||
|
||||
match matches.peek() {
|
||||
Some(m) if m.start() == 0 => {
|
||||
Some(m) if m.start() == 0 || line[0..m.start()].trim_end_matches(' ').is_empty() => {
|
||||
// line starts with neofetch color code, do nothing
|
||||
},
|
||||
_ => {
|
||||
|
@ -545,7 +616,7 @@ fn get_distro_name() -> Result<String> {
|
|||
}
|
||||
|
||||
/// Runs neofetch with colors.
|
||||
#[tracing::instrument(level = "debug")]
|
||||
#[tracing::instrument(level = "debug", skip(asc))]
|
||||
fn run_neofetch(asc: String, args: Option<&Vec<String>>) -> Result<()> {
|
||||
// Escape backslashes here because backslashes are escaped in neofetch for
|
||||
// printf
|
||||
|
|
|
@ -59,7 +59,6 @@ pub enum Preset {
|
|||
Gendervoid,
|
||||
Girlflux,
|
||||
Greygender,
|
||||
#[serde(alias = "biromantic2")]
|
||||
Greysexual,
|
||||
Gynesexual,
|
||||
Intergender,
|
||||
|
@ -433,9 +432,10 @@ impl ColorProfile {
|
|||
pub fn with_length(&self, length: u8) -> Result<Self> {
|
||||
let orig_len = self.colors.len();
|
||||
let orig_len: u8 = orig_len.try_into().expect("`orig_len` should fit in `u8`");
|
||||
if length < orig_len {
|
||||
unimplemented!("compressing length of color profile not implemented");
|
||||
}
|
||||
// TODO: I believe weird things can happen because of this...
|
||||
// if length < orig_len {
|
||||
// unimplemented!("compressing length of color profile not implemented");
|
||||
// }
|
||||
let center_i = (orig_len as f32 / 2.0).floor() as usize;
|
||||
|
||||
// How many copies of each color should be displayed at least?
|
||||
|
@ -448,21 +448,16 @@ impl ColorProfile {
|
|||
|
||||
// If there is an odd space left, extend the center by one space
|
||||
if extras % 2 == 1 {
|
||||
extras -= 1;
|
||||
weights[center_i] += 1;
|
||||
extras -= 1;
|
||||
}
|
||||
|
||||
// Add weight to border until there's no space left (extras must be even at this
|
||||
// point)
|
||||
// TODO: this gives a horrible result when `extras` is still large relative to
|
||||
// `orig_len` - we should probably distribute even if slightly uneven
|
||||
let mut border_i = 0;
|
||||
while extras > 0 {
|
||||
extras -= 2;
|
||||
weights[border_i] += 1;
|
||||
let weights_len = weights.len();
|
||||
for border_i in 0..(extras / 2) as usize {
|
||||
weights[border_i] += 1;
|
||||
weights[weights_len - border_i - 1] += 1;
|
||||
border_i += 1;
|
||||
}
|
||||
|
||||
self.with_weights(weights)
|
||||
|
|
Loading…
Reference in a new issue