Compare commits
91 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dee984f931 | |||
| 959d42ee9c | |||
| eb349aa1aa | |||
| d5751e06af | |||
| 981602b690 | |||
| a8d752aa9f | |||
| c57e8a4a49 | |||
| 67ae918ae8 | |||
| e788f93c2b | |||
| 75a2e9d8d3 | |||
| 23888c0e3e | |||
| e5ad9e564d | |||
| 328381b336 | |||
| 28a181d97b | |||
| bb514f8fd9 | |||
| b585ee1e26 | |||
| de2141347e | |||
| ba88581ed4 | |||
| 932042b62c | |||
| f5c5e31691 | |||
| 15ca855a04 | |||
| 666d2dc90a | |||
| 34583294c6 | |||
| 03615ab4ee | |||
| c722c73e79 | |||
| 8f5199974b | |||
| 8168877fb1 | |||
| 4e20b18d45 | |||
| 5dc1709f58 | |||
| fb1e35172e | |||
| fc9292be3f | |||
| 3f41cb40e2 | |||
| 729024a45f | |||
| ef1407d00e | |||
| 075fc467d2 | |||
| a463f4234c | |||
| beb04101db | |||
| bf60e4265b | |||
| 42421bc57d | |||
| f64ee7b7e9 | |||
| 1fa29cf831 | |||
| 4861dd5d4a | |||
| 5614b723fd | |||
| 5e1e13b091 | |||
| 79ddb3ca92 | |||
| 684929edea | |||
| f02ec8c4ba | |||
| 5fd4ed9b0c | |||
| 003c295084 | |||
| d4560e3edb | |||
| 62b4c27404 | |||
| 169368a784 | |||
| 3e47640c1a | |||
| 6ddd762b35 | |||
| 713bcce0ec | |||
| fdfd9816f5 | |||
| d6f9d1f569 | |||
| b28aa0ddf2 | |||
| a5e784c528 | |||
| 93b4dd3471 | |||
| d15afe579f | |||
| f79aca3c65 | |||
| fa3fc59a5f | |||
| afa3c1dfb9 | |||
| cf6b77a1b7 | |||
| b58425badd | |||
| 8c1713c37d | |||
| 3c7c449da4 | |||
| 2fe4b3f287 | |||
| 6a80928f10 | |||
| 4ac698817d | |||
| 13acc0b6b6 | |||
| 455f0382e7 | |||
| 0c9e4db742 | |||
| aee058e591 | |||
| b74787768f | |||
| 218c535d06 | |||
| 76ae5e507a | |||
| d2dfd950a3 | |||
| 45ee7e199e | |||
| 2cfea54a88 | |||
| 0cc6ddbca8 | |||
| 8a536c30f0 | |||
| 5c24bd443a | |||
| e691b2d9da | |||
| 5ec7b4f01a | |||
| f38b754783 | |||
| 211beb7b6a | |||
| 02c64ef281 | |||
| 4e9c510240 | |||
| d6b559fb40 |
+12
-1
@@ -120,4 +120,15 @@ webhook-log
|
||||
start_moderation.sh
|
||||
gh_moderator.toml
|
||||
moderator-data
|
||||
hyfetch/git
|
||||
hyfetch/git
|
||||
build
|
||||
dist
|
||||
target
|
||||
.vscode
|
||||
.idea
|
||||
*.iml
|
||||
*.egg-info
|
||||
__pycache__
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
|
||||
Generated
+333
-244
File diff suppressed because it is too large
Load Diff
+8
-8
@@ -3,7 +3,7 @@ resolver = "2"
|
||||
members = ["crates/*"]
|
||||
|
||||
[workspace.package]
|
||||
version = "2.0.0-rc1"
|
||||
version = "2.0.3"
|
||||
authors = ["Azalea Gui <azalea@hydev.org>"]
|
||||
edition = "2021"
|
||||
rust-version = "1.75.0"
|
||||
@@ -17,14 +17,14 @@ ansi_colours = { version = "1.2.2", default-features = false }
|
||||
anstream = { version = "0.6.14", default-features = false }
|
||||
anyhow = { version = "1.0.86", default-features = false }
|
||||
bpaf = { version = "0.9.12", default-features = false }
|
||||
crossterm = { version = "0.27.0", default-features = false }
|
||||
crossterm = { version = "0.29.0", default-features = false }
|
||||
deranged = { version = "0.3.11", default-features = false }
|
||||
directories = { version = "5.0.1", default-features = false }
|
||||
directories = { version = "6.0.0", default-features = false }
|
||||
enable-ansi-support = { version = "0.2.1", default-features = false }
|
||||
enterpolation = { version = "0.2.1", default-features = false }
|
||||
fastrand = { version = "2.1.0", default-features = false }
|
||||
indexmap = { version = "2.2.6", default-features = false }
|
||||
itertools = { version = "0.13.0", default-features = false }
|
||||
itertools = { version = "0.14.0", default-features = false }
|
||||
normpath = { version = "1.2.0", default-features = false }
|
||||
palette = { version = "0.7.6", default-features = false }
|
||||
regex = { version = "1.10.5", default-features = false }
|
||||
@@ -33,14 +33,14 @@ serde = { version = "1.0.203", default-features = false }
|
||||
serde_json = { version = "1.0.118", default-features = false }
|
||||
serde_path_to_error = { version = "0.1.16", default-features = false }
|
||||
shell-words = { version = "1.1.0", default-features = false }
|
||||
strum = { version = "0.26.3", default-features = false }
|
||||
strum = { version = "0.27.2", default-features = false }
|
||||
supports-color = { version = "3.0.0", default-features = false }
|
||||
tempfile = { version = "3.10.1", default-features = false }
|
||||
terminal-colorsaurus = { version = "0.4.3", default-features = false }
|
||||
terminal_size = { version = "0.3.0", default-features = false }
|
||||
terminal-colorsaurus = { version = "1.0.0", default-features = false }
|
||||
terminal_size = { version = "0.4.3", default-features = false }
|
||||
thiserror = { version = "1.0.61", default-features = false }
|
||||
time = { version = "0.3.36", default-features = false }
|
||||
toml_edit = { version = "0.22.16", default-features = false }
|
||||
toml_edit = { version = "0.23.6", default-features = false }
|
||||
tracing = { version = "0.1.40", default-features = false }
|
||||
tracing-subscriber = { version = "0.3.18", default-features = false }
|
||||
unicode-normalization = { version = "0.1.23", default-features = false }
|
||||
|
||||
@@ -124,11 +124,102 @@ Updates to `neowofetch` begins with the emoji 🖼️
|
||||
Note: You can install the latest nightly version by using:
|
||||
|
||||
```sh
|
||||
pip install git+https://github.com/hykilpikonna/hyfetch.git@master
|
||||
cargo install --git https://github.com/hykilpikonna/hyfetch
|
||||
```
|
||||
|
||||
<!-- CHANGELOG STARTS HERE --->
|
||||
|
||||
### 2.0.3
|
||||
|
||||
(changelog is generated by Gemini from commit history)
|
||||
|
||||
This update brings a significant internal refactor to how color presets are managed, along with a new batch of pride flags and several important bug fixes.
|
||||
|
||||
**✨ Features & Enhancements**
|
||||
|
||||
* **Custom ASCII Art**: You can now specify a file path for custom ASCII art ([#429](https://github.com/hykilpikonna/hyfetch/pull/429)).
|
||||
* **Hex Color Presets**: Added the ability to pass a custom comma-separated hex color string list (e.g., `#RRGGBB,#RRGGBB`) directly as a preset ([#435](https://github.com/hykilpikonna/hyfetch/pull/435)).
|
||||
|
||||
**🏳️🌈 New Flags**
|
||||
|
||||
* Added Transbian flag ([#449](https://github.com/hykilpikonna/hyfetch/pull/449))
|
||||
* Added Autism Pride flag ([#450](https://github.com/hykilpikonna/hyfetch/pull/450))
|
||||
* Added Transneutral & Cenelian flags ([#452](https://github.com/hykilpikonna/hyfetch/pull/452))
|
||||
* Added Fluidflux flags ([#437](https://github.com/hykilpikonna/hyfetch/pull/437))
|
||||
* Added Libragender flags ([#433](https://github.com/hykilpikonna/hyfetch/pull/433))
|
||||
|
||||
**🐛 Bug Fixes**
|
||||
|
||||
* **Crash Fix**: Fixed a panic that could occur if hyfetch was run on a distro with no defined ASCII art ([#455](https://github.com/hykilpikonna/hyfetch/pull/455)).
|
||||
* **OS Support**: Added support for iOS 1.x ([#444](https://github.com/hykilpikonna/hyfetch/pull/444)) and old Apple TV models ([#438](https://github.com/hykilpikonna/hyfetch/pull/438)).
|
||||
* **Python**:
|
||||
* Fixed a bug where 3-length hex codes (e.g., `#FFF`) does not work properly ([#443](https://github.com/hykilpikonna/hyfetch/pull/443)).
|
||||
* Fixed a string formatting issue for python 3.11 and earlier versions ([#442](https://github.com/hykilpikonna/hyfetch/pull/442)).
|
||||
* Fixed a bug where extra top padding would appear above output ascii art ([#428](https://github.com/hykilpikonna/hyfetch/pull/428)).
|
||||
* **Rust**:
|
||||
* Fixed the logic for the pride month easter egg so it only marks itself as "displayed" during June ([#430](https://github.com/hykilpikonna/hyfetch/pull/430)).
|
||||
* Fixed a build issue on Windows ([#439](https://github.com/hykilpikonna/hyfetch/pull/439)).
|
||||
|
||||
**🔧 Maintenance & Refactoring**
|
||||
|
||||
* **Preset Refactor**: Color presets are now stored in a central `presets.json` file. ([#451](https://github.com/hykilpikonna/hyfetch/issues/451)).
|
||||
* **Dependency Updates**: Upgraded various Rust crates and other dependencies to their latest versions.
|
||||
* **Code Cleanup**: General code shortening and readability improvements.
|
||||
|
||||
### 2.0.2
|
||||
|
||||
This is a small patch release that adds more flags and fixes some bugs from the recent Rust rewrite.
|
||||
|
||||
* 🏳️🌈 **New Flags**: Added new pride flags for Nullflux ([#397](https://github.com/hykilpikonna/hyfetch/pull/397)), Hypergender ([#422](https://github.com/hykilpikonna/hyfetch/pull/422)), Fictosexual ([#394](https://github.com/hykilpikonna/hyfetch/pull/394)), and Adipophilia ([#424](https://github.com/hykilpikonna/hyfetch/pull/424)).
|
||||
* 🐛 **Bug Fixes**:
|
||||
* Fixed a critical bug where custom `fastfetch` configurations could break hyfetch ([#420](https://github.com/hykilpikonna/hyfetch/pull/420)).
|
||||
* Corrected the `nixos_small` ASCII logo to display properly ([#421](https://github.com/hykilpikonna/hyfetch/pull/421)).
|
||||
* 🔧 **Improvements**:
|
||||
* Improved a warning message for better clarity ([#419](https://github.com/hykilpikonna/hyfetch/issues/419)).
|
||||
|
||||
### 2.0.1
|
||||
|
||||
(changelog is generated by Gemini from commit history)
|
||||
|
||||
**🦀 The Rust Rewrite!**
|
||||
|
||||
This is a massive update, rewriting the entire hyfetch core from Python to Rust for significantly improved performance, reliability, and maintainability. A huge thank you to **@teohhanhui** and all the contributors who made this possible!
|
||||
|
||||
* 🚀 **Complete Rewrite in Rust**: The entire codebase has been ported to Rust, resulting in major performance improvements and a smaller binary size.
|
||||
* ⚙️ **New Backends**: In addition to neofetch and fastfetch, hyfetch now supports **macchina** as a backend option.
|
||||
* 🌈 **Improved June Animation**: The `--june` pride month animation is now smoother, flicker-free ([#408](https://github.com/hykilpikonna/hyfetch/pull/408)).
|
||||
* 🪟 **Native Windows Support**: The Rust version provides much-improved support for Windows.
|
||||
|
||||
**✨ Features & Enhancements**
|
||||
|
||||
* 🎨 **Automatic Theme Detection**: Hyfetch can now automatically detect your terminal's light/dark mode (when auto_detect_light_dark is true) ([#380](https://github.com/hykilpikonna/hyfetch/pull/380)).
|
||||
* ✍️ **Font Logos**: Added a new feature to display a logo created from your system's font.
|
||||
* 🌐 **Cloudflare for Public IP**: Now uses Cloudflare to fetch the public IP address, with a fallback option ([#416](https://github.com/hykilpikonna/hyfetch/pull/416)).
|
||||
* 🖼️ **Interactive Logo Selection**: An interactive setup step now allows you to choose between default and small logo variants for your distro ([#392](https://github.com/hykilpikonna/hyfetch/pull/392)).
|
||||
* 🏳️🌈 **New Pride Flags**: Added flags for Cisgender ([#386](https://github.com/hykilpikonna/hyfetch/pull/386)), Kessoku Band ([#384](https://github.com/hykilpikonna/hyfetch/pull/384)), and Watermelon Cream Lozenges ([#369](https://github.com/hykilpikonna/hyfetch/pull/369)) for memes.
|
||||
* 📄 **Page Navigation**: Added `n` and `p` as shorthands for next/previous page selection and implemented page number roll-over ([#372](https://github.com/hykilpikonna/hyfetch/pull/372)).
|
||||
|
||||
**🖼️ New & Updated Distro Support**
|
||||
|
||||
* **Added Bazzite** ([#406](https://github.com/hykilpikonna/hyfetch/pull/406))
|
||||
* **Added Rhino Linux Logo** ([#407](https://github.com/hykilpikonna/hyfetch/pull/407))
|
||||
* **Updated openSUSE Logos & Added Slowroll**
|
||||
* **Updated KSLinux Detection** ([#395](https://github.com/hykilpikonna/hyfetch/pull/395))
|
||||
|
||||
**🐛 Bug Fixes**
|
||||
|
||||
* **macOS**: Fixed CPU and memory fetching on older macOS versions like Leopard and Tiger ([#387](https://github.com/hykilpikonna/hyfetch/pull/387), [#389](https://github.com/hykilpikonna/hyfetch/pull/389)).
|
||||
* **Packaging**: Resolved several issues with `cargo publish` to ensure reliable package deployment ([#405](https://github.com/hykilpikonna/hyfetch/pull/405)).
|
||||
* **Performance**: Sped up RPM package counting by skipping digest and signature verification ([#371](https://github.com/hykilpikonna/hyfetch/pull/371)).
|
||||
* **Animation**: Updated logic to ensure the pride month animation is always shown when `--june` is explicitly used ([#411](https://github.com/hykilpikonna/hyfetch/pull/411)).
|
||||
* **General**: Fixed numerous bugs related to builds, path detection, cache handling, and distro name detection.
|
||||
* **Formatting**: Fixed an unwanted space in the Python version output ([#401](https://github.com/hykilpikonna/hyfetch/pull/401)).
|
||||
|
||||
**🔧 Maintenance**
|
||||
|
||||
* **Documentation**: Updated the README with additional credits for Slackware contributors ([#365](https://github.com/hykilpikonna/hyfetch/pull/365)).
|
||||
* **Build System**: Overhauled the build scripts for Rust, including support for `musl` static builds and cross-compilation for macOS and Windows.
|
||||
|
||||
### 1.99.0
|
||||
|
||||
This version would be the last version of HyFetch on Python as we migrate to Rust (Huge thanks to everyone on [#317](https://github.com/hykilpikonna/hyfetch/pull/317)!). It will also be an effort to start a transition that phases out the neowofetch/neofetch backend in favor of FastFetch, since the time needed to maintain the NF backend currently exceed our capacity. If you are willing to help maintaining it, please let us know!
|
||||
|
||||
@@ -41,9 +41,14 @@ unicode-segmentation = { workspace = true, features = [] }
|
||||
which = { workspace = true, features = [] }
|
||||
|
||||
[build-dependencies]
|
||||
indexmap = { workspace = true, features = ["std"] }
|
||||
indexmap = { workspace = true, features = ["std", "serde"] }
|
||||
regex = { workspace = true, features = ["perf", "std", "unicode"] }
|
||||
unicode-normalization = { workspace = true, features = ["std"] }
|
||||
fs_extra = "1.3.0"
|
||||
serde = { workspace = true, features = ["derive", "std"] }
|
||||
serde_json = { workspace = true, features = ["std"] }
|
||||
anyhow = { workspace = true, features = ["std"] }
|
||||
heck = "0.5.0"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
enable-ansi-support = { workspace = true, features = [] }
|
||||
|
||||
+123
-58
@@ -1,9 +1,14 @@
|
||||
use std::env;
|
||||
use std::fmt::Write as _;
|
||||
use std::path::Path;
|
||||
use std::{env, fs};
|
||||
|
||||
use std::fs;
|
||||
use std::io::{BufWriter, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use anyhow::{Context, Result};
|
||||
use fs_extra::dir::CopyOptions;
|
||||
use heck::ToUpperCamelCase;
|
||||
use indexmap::IndexMap;
|
||||
use regex::Regex;
|
||||
use serde::Deserialize;
|
||||
use unicode_normalization::UnicodeNormalization as _;
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -23,25 +28,40 @@ impl AsciiDistro {
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let neofetch_path = Path::new(env!("CARGO_WORKSPACE_DIR")).join("neofetch");
|
||||
|
||||
println!(
|
||||
"cargo:rerun-if-changed={neofetch_path}",
|
||||
neofetch_path = neofetch_path.display()
|
||||
);
|
||||
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
let out_path = Path::new(&out_dir);
|
||||
|
||||
export_distros(neofetch_path, out_path);
|
||||
fn anything_that_exist(paths: &[&Path]) -> Option<PathBuf> {
|
||||
paths.iter().copied().find(|p| p.exists()).map(Path::to_path_buf)
|
||||
}
|
||||
|
||||
fn export_distros<P>(neofetch_path: P, out_path: &Path)
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
fn main() -> Result<()> {
|
||||
// Path hack to make file paths work in both workspace and manifest directory
|
||||
let dir = PathBuf::from(env::var_os("CARGO_WORKSPACE_DIR").unwrap_or_else(|| env::var_os("CARGO_MANIFEST_DIR").unwrap()));
|
||||
let o = PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||
|
||||
for file in &["neofetch", "hyfetch/data"] {
|
||||
let src = anything_that_exist(&[
|
||||
&dir.join(file),
|
||||
&dir.join("../../").join(file),
|
||||
]).context("couldn't find neofetch")?;
|
||||
let dst = o.join(file);
|
||||
println!("cargo:rerun-if-changed={}", src.display());
|
||||
|
||||
// Copy either file or directory
|
||||
if src.is_dir() {
|
||||
let opt = CopyOptions { overwrite: true, copy_inside: true, ..CopyOptions::default() };
|
||||
println!("copying {} to {}", src.display(), dst.display());
|
||||
fs_extra::dir::copy(&src, &dst, &opt)?;
|
||||
}
|
||||
else { fs::copy(&src, &dst)?; }
|
||||
}
|
||||
|
||||
preset_codegen(&o.join("hyfetch/data/presets.json"), &o.join("presets.rs"))?;
|
||||
export_distros(&o.join("neofetch"), &o)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn export_distros(neofetch_path: &Path, out_path: &Path) -> Result<()>
|
||||
{
|
||||
let distros = parse_ascii_distros(neofetch_path);
|
||||
let distros = parse_ascii_distros(neofetch_path)?;
|
||||
let mut variants = IndexMap::with_capacity(distros.len());
|
||||
|
||||
for distro in &distros {
|
||||
@@ -64,18 +84,13 @@ where
|
||||
let mut buf = r###"
|
||||
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
||||
pub enum Distro {
|
||||
"###
|
||||
.to_owned();
|
||||
"###.to_string();
|
||||
|
||||
for (variant, AsciiDistro { pattern, .. }) in &variants {
|
||||
write!(
|
||||
buf,
|
||||
r###"
|
||||
write!(buf, r###"
|
||||
// {pattern})
|
||||
{variant},
|
||||
"###,
|
||||
)
|
||||
.unwrap();
|
||||
"###)?;
|
||||
}
|
||||
|
||||
buf.push_str(
|
||||
@@ -137,15 +152,11 @@ impl Distro {
|
||||
|
||||
let condition = conds.join(" || ");
|
||||
|
||||
write!(
|
||||
buf,
|
||||
r###"
|
||||
write!(buf, r###"
|
||||
if {condition} {{
|
||||
return Some(Self::{variant});
|
||||
}}
|
||||
"###
|
||||
)
|
||||
.unwrap();
|
||||
"###)?;
|
||||
}
|
||||
|
||||
buf.push_str(
|
||||
@@ -160,15 +171,11 @@ impl Distro {
|
||||
|
||||
let quotes = "#".repeat(80);
|
||||
for (variant, AsciiDistro { art, .. }) in &variants {
|
||||
write!(
|
||||
buf,
|
||||
r###"
|
||||
write!(buf, r###"
|
||||
Self::{variant} => r{quotes}"
|
||||
{art}
|
||||
"{quotes},
|
||||
"###,
|
||||
)
|
||||
.unwrap();
|
||||
"###)?;
|
||||
}
|
||||
|
||||
buf.push_str(
|
||||
@@ -180,26 +187,23 @@ impl Distro {
|
||||
"###,
|
||||
);
|
||||
|
||||
fs::write(out_path.join("distros.rs"), buf).expect("couldn't write distros.rs");
|
||||
fs::write(out_path.join("distros.rs"), buf)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parses ascii distros from neofetch script.
|
||||
fn parse_ascii_distros<P>(neofetch_path: P) -> Vec<AsciiDistro>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
fn parse_ascii_distros(neofetch_path: &Path) -> Result<Vec<AsciiDistro>>
|
||||
{
|
||||
let neofetch_path = neofetch_path.as_ref();
|
||||
|
||||
let nf = {
|
||||
let nf = fs::read_to_string(neofetch_path).expect("couldn't read neofetch script");
|
||||
let nf = fs::read_to_string(neofetch_path)?;
|
||||
|
||||
// Get the content of "get_distro_ascii" function
|
||||
let (_, nf) = nf
|
||||
.split_once("get_distro_ascii() {\n")
|
||||
.expect("couldn't find get_distro_ascii function");
|
||||
.context("couldn't find get_distro_ascii function")?;
|
||||
let (nf, _) = nf
|
||||
.split_once("\n}\n")
|
||||
.expect("couldn't find end of get_distro_ascii function");
|
||||
.context("couldn't find end of get_distro_ascii function")?;
|
||||
|
||||
let mut nf = nf.replace('\t', &" ".repeat(4));
|
||||
|
||||
@@ -210,8 +214,8 @@ where
|
||||
nf
|
||||
};
|
||||
|
||||
let case_re = Regex::new(r"case .*? in\n").expect("couldn't compile case regex");
|
||||
let eof_re = Regex::new(r"EOF[ \n]*?;;").expect("couldn't compile eof regex");
|
||||
let case_re = Regex::new(r"case .*? in\n")?;
|
||||
let eof_re = Regex::new(r"EOF[ \n]*?;;")?;
|
||||
|
||||
// Split by blocks
|
||||
let mut blocks = Vec::new();
|
||||
@@ -245,13 +249,74 @@ where
|
||||
// for printf
|
||||
let art = art.replace(r"\\", r"\");
|
||||
|
||||
Some(AsciiDistro {
|
||||
pattern: pattern.to_owned(),
|
||||
art,
|
||||
})
|
||||
Some(AsciiDistro { pattern: pattern.to_owned(), art })
|
||||
}
|
||||
blocks
|
||||
.iter()
|
||||
.filter_map(|block| parse_block(block))
|
||||
.collect()
|
||||
Ok(blocks.iter().filter_map(|block| parse_block(block)).collect())
|
||||
}
|
||||
|
||||
// Preset parsing
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[serde(untagged)]
|
||||
enum PresetEntry {
|
||||
Simple(Vec<String>),
|
||||
Complex { colors: Vec<String>, weights: Option<Vec<u32>> },
|
||||
}
|
||||
|
||||
type PresetMap = IndexMap<String, PresetEntry>;
|
||||
|
||||
fn preset_codegen(json_path: &Path, out_path: &Path) -> Result<()> {
|
||||
// 1. Read and parse the JSON file
|
||||
let json_str = fs::read_to_string(json_path)?;
|
||||
let map: PresetMap = serde_json::from_str(&json_str)?;
|
||||
let mut f = BufWriter::new(fs::File::create(&out_path)?);
|
||||
|
||||
// 2. Build the code string
|
||||
let mut code_decl = String::new();
|
||||
let mut code_match = String::new();
|
||||
for (key, data) in map.iter() {
|
||||
let colors = match data {
|
||||
PresetEntry::Simple(c) => c,
|
||||
PresetEntry::Complex { colors, .. } => colors,
|
||||
};
|
||||
let colors = colors.iter().map(|s| format!("\"{}\"", s)).collect::<Vec<_>>().join(", ");
|
||||
let uck = key.to_upper_camel_case();
|
||||
|
||||
code_decl += &format!(r#"
|
||||
#[serde(rename = "{key}")]
|
||||
#[strum(serialize = "{key}")]
|
||||
{uck},
|
||||
"#);
|
||||
|
||||
let w = if let PresetEntry::Complex { weights: Some(w), .. } = data {
|
||||
format!(".and_then(|c| c.with_weights(vec![{}]))", w.iter().map(|n| n.to_string()).collect::<Vec<_>>().join(", "))
|
||||
} else { "".to_string() };
|
||||
|
||||
code_match += &format!(r#"
|
||||
Preset::{uck} => ColorProfile::from_hex_colors(vec![{colors}]){w},
|
||||
"#);
|
||||
}
|
||||
|
||||
// 3. Write the static map to the generated file
|
||||
writeln!(f, r#"
|
||||
pub use crate::color_profile::ColorProfile;
|
||||
use serde::{{Deserialize, Serialize}};
|
||||
use strum::{{AsRefStr, EnumCount, EnumString, VariantArray, VariantNames}};
|
||||
|
||||
#[derive(Copy, Clone, Hash, Debug, AsRefStr, Deserialize, EnumCount, EnumString, Serialize, VariantArray, VariantNames)]
|
||||
pub enum Preset {{
|
||||
{code_decl}
|
||||
}}
|
||||
|
||||
impl Preset {{
|
||||
pub fn color_profile(&self) -> ColorProfile {{
|
||||
(match self {{
|
||||
{code_match}
|
||||
}})
|
||||
.expect("preset color profiles should be valid")
|
||||
}}
|
||||
}}"#)?;
|
||||
|
||||
f.flush()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -61,8 +61,8 @@ impl RawAsciiArt {
|
||||
|
||||
Ok(NormalizedAsciiArt {
|
||||
lines,
|
||||
w,
|
||||
h,
|
||||
w: w.try_into().context("width does not fit in u8")?,
|
||||
h: h.try_into().context("height does not fit in u8")?,
|
||||
fg: self.fg.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
+318
-261
@@ -2,7 +2,8 @@ use std::borrow::Cow;
|
||||
use std::cmp;
|
||||
use std::fmt::Write as _;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{self, IsTerminal as _, Read as _, Write as _};
|
||||
use std::io::{self, IsTerminal as _, Read as _};
|
||||
use std::iter;
|
||||
use std::iter::zip;
|
||||
use std::num::NonZeroU8;
|
||||
use std::path::{Path, PathBuf};
|
||||
@@ -13,17 +14,20 @@ use deranged::RangedU8;
|
||||
use enterpolation::bspline::BSpline;
|
||||
use enterpolation::{Curve as _, Generator as _};
|
||||
use hyfetch::ascii::RawAsciiArt;
|
||||
use hyfetch::ascii::NormalizedAsciiArt;
|
||||
use hyfetch::cli_options::options;
|
||||
use hyfetch::color_util::{
|
||||
clear_screen, color, printc, ContrastGrayscale as _, ForegroundBackground, Lightness,
|
||||
NeofetchAsciiIndexedColor, PresetIndexedColor, Theme as _, ToAnsiString as _,
|
||||
};
|
||||
use hyfetch::distros::Distro;
|
||||
use hyfetch::models::Config;
|
||||
#[cfg(feature = "macchina")]
|
||||
use hyfetch::neofetch_util::macchina_path;
|
||||
use hyfetch::neofetch_util::{self, add_pkg_path, fastfetch_path, get_distro_ascii, literal_input, ColorAlignment, NEOFETCH_COLORS_AC, NEOFETCH_COLOR_PATTERNS, TEST_ASCII};
|
||||
use hyfetch::presets::{AssignLightness, Preset};
|
||||
use hyfetch::pride_month;
|
||||
use hyfetch::neofetch_util::{self, add_pkg_path, fastfetch_path, get_distro_ascii, get_distro_name, literal_input, ColorAlignment, NEOFETCH_COLORS_AC, NEOFETCH_COLOR_PATTERNS, TEST_ASCII};
|
||||
use hyfetch::color_profile::{AssignLightness, ColorProfile};
|
||||
use hyfetch::presets::{Preset};
|
||||
use hyfetch::{pride_month, printc};
|
||||
use hyfetch::types::{AnsiMode, Backend, TerminalTheme};
|
||||
use hyfetch::utils::{get_cache_path, input};
|
||||
use hyfetch::font_logo::get_font_logo;
|
||||
@@ -62,15 +66,12 @@ fn main() -> Result<()> {
|
||||
});
|
||||
|
||||
if options.test_print {
|
||||
let asc = get_distro_ascii(distro, backend).context("failed to get distro ascii")?;
|
||||
writeln!(io::stdout(), "{asc}", asc = asc.asc)
|
||||
.context("failed to write ascii to stdout")?;
|
||||
println!("{asc}", asc = get_distro_ascii(distro, backend)?.asc);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if options.print_font_logo {
|
||||
let logo = get_font_logo(backend).context("failed to get font logo")?;
|
||||
writeln!(io::stdout(), "{}", logo).context("failed to write logo to stdout")?;
|
||||
println!("{}", get_font_logo(backend)?);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -87,7 +88,16 @@ fn main() -> Result<()> {
|
||||
};
|
||||
|
||||
let color_mode = options.mode.unwrap_or(config.mode);
|
||||
let theme = config.light_dark;
|
||||
let auto_detect_light_dark = options
|
||||
.auto_detect_light_dark
|
||||
.unwrap_or_else(|| config.auto_detect_light_dark.unwrap_or(false));
|
||||
let theme = if auto_detect_light_dark {
|
||||
let res = det_bg();
|
||||
res?.map(|bg| bg.theme())
|
||||
.unwrap_or(config.light_dark.unwrap_or_default())
|
||||
} else {
|
||||
config.light_dark.unwrap_or_default()
|
||||
};
|
||||
|
||||
// Check if it's June (pride month)
|
||||
let now =
|
||||
@@ -99,16 +109,9 @@ fn main() -> Result<()> {
|
||||
|
||||
if show_pride_month && !config.pride_month_disable {
|
||||
pride_month::start_animation(color_mode).context("failed to draw pride month animation")?;
|
||||
writeln!(
|
||||
io::stdout(),
|
||||
"\nHappy pride month!\n(You can always view the animation again with `hyfetch \
|
||||
--june`)\n"
|
||||
)
|
||||
.context("failed to write message to stdout")?;
|
||||
println!("\nHappy pride month!\n(You can always view the animation again with `hyfetch --june`)\n");
|
||||
|
||||
if !june_path.is_file() {
|
||||
fs::create_dir_all(&cache_path)
|
||||
.with_context(|| format!("failed to create cache dir {cache_path:?}"))?;
|
||||
if !june_path.is_file() && !options.june {
|
||||
File::create(&june_path)
|
||||
.with_context(|| format!("failed to create file {june_path:?}"))?;
|
||||
}
|
||||
@@ -120,9 +123,43 @@ fn main() -> Result<()> {
|
||||
let backend = options.backend.unwrap_or(config.backend);
|
||||
let args = options.args.as_ref().or(config.args.as_ref());
|
||||
|
||||
fn parse_preset_string(preset_string: &str) -> Result<ColorProfile> {
|
||||
if preset_string.contains('#') {
|
||||
let colors: Vec<&str> = preset_string.split(',').map(|s| s.trim()).collect();
|
||||
for color in &colors {
|
||||
if !color.starts_with('#') ||
|
||||
(color.len() != 4 && color.len() != 7) ||
|
||||
!color[1..].chars().all(|c| c.is_ascii_hexdigit()) {
|
||||
return Err(anyhow::anyhow!("invalid hex color: {}", color));
|
||||
}
|
||||
}
|
||||
ColorProfile::from_hex_colors(colors)
|
||||
.context("failed to create color profile from hex")
|
||||
} else if preset_string == "random" {
|
||||
let mut rng = fastrand::Rng::new();
|
||||
let preset = *rng
|
||||
.choice(<Preset as VariantArray>::VARIANTS)
|
||||
.expect("preset iterator should not be empty");
|
||||
Ok(preset.color_profile())
|
||||
} else {
|
||||
use std::str::FromStr;
|
||||
let preset = Preset::from_str(preset_string)
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"PRESET should be comma-separated hex colors or one of {{{presets}}}",
|
||||
presets = <Preset as VariantNames>::VARIANTS
|
||||
.iter()
|
||||
.chain(iter::once(&"random"))
|
||||
.join(",")
|
||||
)
|
||||
})?;
|
||||
Ok(preset.color_profile())
|
||||
}
|
||||
}
|
||||
|
||||
// Get preset
|
||||
let preset = options.preset.unwrap_or(config.preset);
|
||||
let color_profile = preset.color_profile();
|
||||
let preset_string = options.preset.as_deref().unwrap_or(&config.preset);
|
||||
let color_profile = parse_preset_string(preset_string)?;
|
||||
debug!(?color_profile, "color profile");
|
||||
|
||||
// Lighten
|
||||
@@ -131,11 +168,23 @@ fn main() -> Result<()> {
|
||||
} else if let Some(lightness) = options.lightness {
|
||||
color_profile.with_lightness(AssignLightness::Replace(lightness))
|
||||
} else {
|
||||
color_profile.with_lightness_adaptive(config.lightness(), theme)
|
||||
color_profile.with_lightness_adaptive(
|
||||
config
|
||||
.lightness
|
||||
.unwrap_or_else(|| Config::default_lightness(theme)),
|
||||
theme,
|
||||
)
|
||||
};
|
||||
debug!(?color_profile, "lightened color profile");
|
||||
|
||||
let asc = if let Some(path) = options.ascii_file {
|
||||
let asc = if let Some(path_str) = config.custom_ascii_path {
|
||||
let path = PathBuf::from(path_str);
|
||||
RawAsciiArt {
|
||||
asc: fs::read_to_string(&path)
|
||||
.with_context(|| format!("failed to read ascii from {path:?}"))?,
|
||||
fg: Vec::new(),
|
||||
}
|
||||
} else if let Some(path) = options.ascii_file {
|
||||
RawAsciiArt {
|
||||
asc: fs::read_to_string(&path)
|
||||
.with_context(|| format!("failed to read ascii from {path:?}"))?,
|
||||
@@ -187,6 +236,22 @@ fn load_config(path: &PathBuf) -> Result<Option<Config>> {
|
||||
Ok(Some(config))
|
||||
}
|
||||
|
||||
fn det_bg() -> Result<Option<Srgb<u8>>, terminal_colorsaurus::Error> {
|
||||
if !io::stdout().is_terminal() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
background_color(QueryOptions::default())
|
||||
.map(|terminal_colorsaurus::Color { r, g, b , .. }| Some(Srgb::new(r, g, b).into_format()))
|
||||
.or_else(|err| {
|
||||
if matches!(err, terminal_colorsaurus::Error::UnsupportedTerminal(_)) {
|
||||
Ok(None)
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates config interactively.
|
||||
///
|
||||
/// The config is automatically stored to file.
|
||||
@@ -197,30 +262,15 @@ fn create_config(
|
||||
backend: Backend,
|
||||
debug_mode: bool,
|
||||
) -> Result<Config> {
|
||||
// Detect terminal environment (doesn't work for all terminal emulators,
|
||||
// especially on Windows)
|
||||
let det_bg = if io::stdout().is_terminal() {
|
||||
match background_color(QueryOptions::default()) {
|
||||
Ok(bg) => Some(Srgb::<u16>::new(bg.r, bg.g, bg.b).into_format::<u8>()),
|
||||
Err(terminal_colorsaurus::Error::UnsupportedTerminal) => None,
|
||||
Err(err) => {
|
||||
return Err(err).context("failed to get terminal background color");
|
||||
},
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let det_bg = det_bg()?;
|
||||
debug!(?det_bg, "detected background color");
|
||||
let det_ansi = supports_color::on(supports_color::Stream::Stdout).map(|color_level| {
|
||||
#[allow(clippy::if_same_then_else)]
|
||||
if color_level.has_16m {
|
||||
AnsiMode::Rgb
|
||||
} else if color_level.has_256 {
|
||||
AnsiMode::Ansi256
|
||||
} else if color_level.has_basic {
|
||||
// unimplemented!(
|
||||
// "{mode} color mode not supported",
|
||||
// mode = AnsiMode::Ansi16.as_ref()
|
||||
// );
|
||||
AnsiMode::Ansi256
|
||||
} else {
|
||||
unreachable!();
|
||||
@@ -228,9 +278,10 @@ fn create_config(
|
||||
});
|
||||
debug!(?det_ansi, "detected color mode");
|
||||
|
||||
let asc = get_distro_ascii(distro, backend).context("failed to get distro ascii")?;
|
||||
// Try to get ascii from given backend first, if it fails, try neofetch backend
|
||||
let asc = get_distro_ascii(distro, backend).or_else(|_| get_distro_ascii(distro, Backend::Neofetch)).context("failed to get distro ascii from neofetch backend")?;
|
||||
let asc = asc.to_normalized().context("failed to normalize ascii")?;
|
||||
let theme = det_bg.map(|bg| bg.theme()).unwrap_or(TerminalTheme::Light);
|
||||
let theme = det_bg.map(|bg| bg.theme()).unwrap_or_default();
|
||||
let color_mode = det_ansi.unwrap_or(AnsiMode::Ansi256);
|
||||
let mut title = format!(
|
||||
"Welcome to {logo} Let's set up some colors first.",
|
||||
@@ -259,38 +310,19 @@ fn create_config(
|
||||
.expect("`option_counter` should not overflow `u8`");
|
||||
}
|
||||
|
||||
fn print_title_prompt(
|
||||
option_counter: NonZeroU8,
|
||||
prompt: &str,
|
||||
color_mode: AnsiMode,
|
||||
) -> Result<()> {
|
||||
printc(format!("&a{option_counter}. {prompt}"), color_mode)
|
||||
.context("failed to print prompt")
|
||||
fn print_title_prompt(option_counter: NonZeroU8, prompt: &str) {
|
||||
printc!("&a{option_counter}. {prompt}");
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// 0. Check term size
|
||||
|
||||
{
|
||||
let (Width(term_w), Height(term_h)) =
|
||||
terminal_size().context("failed to get terminal size")?;
|
||||
let (term_w_min, term_h_min) = (
|
||||
u16::from(asc.w)
|
||||
.checked_mul(2)
|
||||
.unwrap()
|
||||
.checked_add(4)
|
||||
.unwrap(),
|
||||
30,
|
||||
);
|
||||
let (Width(term_w), Height(term_h)) = terminal_size().context("failed to get terminal size")?;
|
||||
let (term_w_min, term_h_min) = ((asc.w as u32 * 2 + 4).clamp(0, u16::MAX.into()) as u16, 30);
|
||||
if term_w < term_w_min || term_h < term_h_min {
|
||||
printc(
|
||||
format!(
|
||||
"&cWarning: Your terminal is too small ({term_w} * {term_h}).\nPlease resize \
|
||||
it to at least ({term_w_min} * {term_h_min}) for better experience."
|
||||
),
|
||||
color_mode,
|
||||
)
|
||||
.context("failed to print message")?;
|
||||
printc!("&cWarning: Your terminal is too small ({term_w} * {term_h}).\n\
|
||||
Please resize it to at least ({term_w_min} * {term_h_min}) for better experience.");
|
||||
input(Some("Press enter to continue...")).context("failed to read input")?;
|
||||
}
|
||||
}
|
||||
@@ -335,18 +367,14 @@ fn create_config(
|
||||
(t - a) * ((d - c) / (b - a)) + c
|
||||
}
|
||||
|
||||
{
|
||||
let label = format!(
|
||||
"{label:^term_w$}",
|
||||
label = "8bit Color Testing",
|
||||
term_w = usize::from(term_w)
|
||||
);
|
||||
let print_color_testing = |label: &str, mode: AnsiMode| {
|
||||
let label = format!("{label:^term_w$}", term_w = usize::from(term_w));
|
||||
let line = zip(gradient.iter(), label.chars()).fold(
|
||||
String::new(),
|
||||
|mut s, (&rgb_f32_color, t)| {
|
||||
let rgb_u8_color = Srgb::<u8>::from_linear(rgb_f32_color);
|
||||
let back = rgb_u8_color
|
||||
.to_ansi_string(AnsiMode::Ansi256, ForegroundBackground::Background);
|
||||
.to_ansi_string(mode, ForegroundBackground::Background);
|
||||
let fore = rgb_u8_color
|
||||
.contrast_grayscale()
|
||||
.to_ansi_string(AnsiMode::Ansi256, ForegroundBackground::Foreground);
|
||||
@@ -354,42 +382,15 @@ fn create_config(
|
||||
s
|
||||
},
|
||||
);
|
||||
printc(line, AnsiMode::Ansi256).context("failed to print 8-bit color test line")?;
|
||||
}
|
||||
{
|
||||
let label = format!(
|
||||
"{label:^term_w$}",
|
||||
label = "RGB Color Testing",
|
||||
term_w = usize::from(term_w)
|
||||
);
|
||||
let line = zip(gradient.iter(), label.chars()).fold(
|
||||
String::new(),
|
||||
|mut s, (&rgb_f32_color, t)| {
|
||||
let rgb_u8_color = Srgb::<u8>::from_linear(rgb_f32_color);
|
||||
let back = rgb_u8_color
|
||||
.to_ansi_string(AnsiMode::Rgb, ForegroundBackground::Background);
|
||||
let fore = rgb_u8_color
|
||||
.contrast_grayscale()
|
||||
.to_ansi_string(AnsiMode::Ansi256, ForegroundBackground::Foreground);
|
||||
write!(s, "{back}{fore}{t}").unwrap();
|
||||
s
|
||||
},
|
||||
);
|
||||
printc(line, AnsiMode::Rgb).context("failed to print RGB color test line")?;
|
||||
}
|
||||
printc!("{line}");
|
||||
};
|
||||
|
||||
writeln!(io::stdout()).context("failed to write to stdout")?;
|
||||
print_title_prompt(
|
||||
option_counter,
|
||||
"Which &bcolor system &ado you want to use?",
|
||||
color_mode,
|
||||
)
|
||||
.context("failed to print title prompt")?;
|
||||
writeln!(
|
||||
io::stdout(),
|
||||
"(If you can't see colors under \"RGB Color Testing\", please choose 8bit)\n"
|
||||
)
|
||||
.context("failed to write message to stdout")?;
|
||||
print_color_testing("8bit Color Testing", AnsiMode::Ansi256);
|
||||
print_color_testing("RGB Color Testing", AnsiMode::Rgb);
|
||||
|
||||
println!();
|
||||
print_title_prompt(option_counter, "Which &bcolor system &ado you want to use?");
|
||||
println!("(If you can't see colors under \"RGB Color Testing\", please choose 8bit)\n");
|
||||
|
||||
let choice = literal_input(
|
||||
"Your choice?",
|
||||
@@ -422,20 +423,14 @@ fn create_config(
|
||||
|
||||
clear_screen(Some(&title), color_mode, debug_mode).context("failed to clear screen")?;
|
||||
|
||||
print_title_prompt(
|
||||
option_counter,
|
||||
"Is your terminal in &blight mode&~ or &4dark mode&~?",
|
||||
color_mode,
|
||||
)
|
||||
.context("failed to print title prompt")?;
|
||||
print_title_prompt(option_counter, "Is your terminal in &blight mode&~ or &4dark mode&~?");
|
||||
let choice = literal_input(
|
||||
"",
|
||||
TerminalTheme::VARIANTS,
|
||||
TerminalTheme::Dark.as_ref(),
|
||||
true,
|
||||
color_mode,
|
||||
)
|
||||
.context("failed to ask for choice input")?;
|
||||
)?;
|
||||
Ok((
|
||||
choice.parse().expect("selected theme should be valid"),
|
||||
"Selected background color",
|
||||
@@ -483,28 +478,12 @@ fn create_config(
|
||||
|
||||
// Calculate flags per row
|
||||
let (flags_per_row, rows_per_page) = {
|
||||
let (Width(term_w), Height(term_h)) =
|
||||
terminal_size().context("failed to get terminal size")?;
|
||||
let flags_per_row = term_w.div_euclid(u16::from(spacing).checked_add(2).unwrap());
|
||||
let flags_per_row: u8 = flags_per_row
|
||||
.try_into()
|
||||
.expect("`flags_per_row` should fit in `u8`");
|
||||
let rows_per_page = cmp::max(1, term_h.saturating_sub(13).div_euclid(5));
|
||||
let rows_per_page: u8 = rows_per_page
|
||||
.try_into()
|
||||
.expect("`rows_per_page` should fit in `u8`");
|
||||
let (Width(term_w), Height(term_h)) = terminal_size().context("failed to get term size")?;
|
||||
let flags_per_row = (term_w / (spacing as u16 + 2)).clamp(0, u8::MAX.into()) as u8;
|
||||
let rows_per_page = (term_h.saturating_sub(13) / 5).clamp(1, u8::MAX.into()) as u8;
|
||||
(flags_per_row, rows_per_page)
|
||||
};
|
||||
let num_pages =
|
||||
u16::from(u8::try_from(Preset::COUNT).expect("`Preset::COUNT` should fit in `u8`"))
|
||||
.div_ceil(
|
||||
u16::from(flags_per_row)
|
||||
.checked_mul(u16::from(rows_per_page))
|
||||
.unwrap(),
|
||||
);
|
||||
let num_pages: u8 = num_pages
|
||||
.try_into()
|
||||
.expect("`num_pages` should fit in `u8`");
|
||||
let num_pages = (Preset::COUNT.div_ceil(flags_per_row as usize * rows_per_page as usize)).clamp(0, u8::MAX.into()) as u8;
|
||||
|
||||
// Create pages
|
||||
let mut pages = Vec::with_capacity(usize::from(num_pages));
|
||||
@@ -522,18 +501,12 @@ fn create_config(
|
||||
|
||||
let print_flag_page = |page, page_num: u8| -> Result<()> {
|
||||
clear_screen(Some(&title), color_mode, debug_mode).context("failed to clear screen")?;
|
||||
print_title_prompt(option_counter, "Let's choose a flag!", color_mode)
|
||||
.context("failed to print title prompt")?;
|
||||
writeln!(
|
||||
io::stdout(),
|
||||
"Available flag presets:\nPage: {page_num} of {num_pages}\n",
|
||||
page_num = page_num.checked_add(1).unwrap()
|
||||
)
|
||||
.context("failed to write header to stdout")?;
|
||||
print_title_prompt(option_counter, "Let's choose a flag!");
|
||||
println!("Available flag presets:\nPage: {page_num} of {num_pages}\n", page_num = page_num + 1);
|
||||
for &row in page {
|
||||
print_flag_row(row, color_mode).context("failed to print flag row")?;
|
||||
}
|
||||
writeln!(io::stdout()).context("failed to write to stdout")?;
|
||||
println!();
|
||||
Ok(())
|
||||
};
|
||||
|
||||
@@ -545,7 +518,7 @@ fn create_config(
|
||||
}
|
||||
printc(line.join(" "), color_mode).context("failed to print line")?;
|
||||
}
|
||||
writeln!(io::stdout()).context("failed to write to stdout")?;
|
||||
println!();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -570,16 +543,9 @@ fn create_config(
|
||||
let mut opts: Vec<&str> = <Preset as VariantNames>::VARIANTS.into();
|
||||
opts.extend(["next", "n", "prev", "p"]);
|
||||
|
||||
writeln!(
|
||||
io::stdout(),
|
||||
"Enter '[n]ext' to go to the next page and '[p]rev' to go to the previous page."
|
||||
)
|
||||
.context("failed to write message to stdout")?;
|
||||
println!("Enter '[n]ext' to go to the next page and '[p]rev' to go to the previous page.");
|
||||
let selection = literal_input(
|
||||
format!(
|
||||
"Which {preset} do you want to use? ",
|
||||
preset = preset_default_colored
|
||||
),
|
||||
format!("Which {preset_default_colored} do you want to use? "),
|
||||
&opts[..],
|
||||
Preset::Rainbow.as_ref(),
|
||||
false,
|
||||
@@ -628,33 +594,22 @@ fn create_config(
|
||||
|
||||
let select_lightness = || -> Result<Lightness> {
|
||||
clear_screen(Some(&title), color_mode, debug_mode).context("failed to clear screen")?;
|
||||
print_title_prompt(
|
||||
option_counter,
|
||||
"Let's adjust the color brightness!",
|
||||
color_mode,
|
||||
)
|
||||
.context("failed to print title prompt")?;
|
||||
writeln!(
|
||||
io::stdout(),
|
||||
print_title_prompt(option_counter, "Let's adjust the color brightness!");
|
||||
println!(
|
||||
"The colors might be a little bit too {bright_dark} for {light_dark} mode.\n",
|
||||
bright_dark = match theme {
|
||||
TerminalTheme::Light => "bright",
|
||||
TerminalTheme::Dark => "dark",
|
||||
},
|
||||
light_dark = theme.as_ref()
|
||||
)
|
||||
.context("failed to write message to stdout")?;
|
||||
);
|
||||
|
||||
let color_align = ColorAlignment::Horizontal;
|
||||
|
||||
// Print cats
|
||||
{
|
||||
let (Width(term_w), _) = terminal_size().context("failed to get terminal size")?;
|
||||
let num_cols = cmp::max(
|
||||
1,
|
||||
term_w.div_euclid(u16::from(test_ascii.w).checked_add(2).unwrap()),
|
||||
);
|
||||
let num_cols: u8 = num_cols.try_into().expect("`num_cols` should fit in `u8`");
|
||||
let num_cols = (term_w / (test_ascii.w as u16 + 2)).clamp(1, u8::MAX.into()) as u8;
|
||||
const MIN: f32 = 0.15;
|
||||
const MAX: f32 = 0.85;
|
||||
let ratios =
|
||||
@@ -705,14 +660,10 @@ fn create_config(
|
||||
}
|
||||
|
||||
loop {
|
||||
writeln!(
|
||||
io::stdout(),
|
||||
"\nWhich brightness level looks the best? (Default: {default:.0}% for \
|
||||
{light_dark} mode)",
|
||||
println!("\nWhich brightness level looks the best? (Default: {default:.0}% for {light_dark} mode)",
|
||||
default = f32::from(default_lightness) * 100.0,
|
||||
light_dark = theme.as_ref()
|
||||
)
|
||||
.context("failed to write prompt to stdout")?;
|
||||
);
|
||||
let lightness = input(Some("> "))
|
||||
.context("failed to read input")?
|
||||
.trim()
|
||||
@@ -724,12 +675,7 @@ fn create_config(
|
||||
},
|
||||
Err(err) => {
|
||||
debug!(%err, "could not parse lightness");
|
||||
printc(
|
||||
"&cUnable to parse lightness value, please enter a lightness value such \
|
||||
as 45%, .45, or 45",
|
||||
color_mode,
|
||||
)
|
||||
.context("failed to print message")?;
|
||||
printc!("&cUnable to parse lightness value, please enter a lightness value such as 45%, .45, or 45");
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -764,33 +710,129 @@ fn create_config(
|
||||
);
|
||||
|
||||
//////////////////////////////
|
||||
// 5. Color arrangement
|
||||
|
||||
let color_align: ColorAlignment;
|
||||
// 5. Choose Default or Small Logo
|
||||
|
||||
// Calculate amount of row/column that can be displayed on screen
|
||||
let (ascii_per_row, ascii_rows) = {
|
||||
let (Width(term_w), Height(term_h)) =
|
||||
terminal_size().context("failed to get terminal size")?;
|
||||
let ascii_per_row = cmp::max(
|
||||
1,
|
||||
term_w.div_euclid(u16::from(asc.w).checked_add(2).unwrap()),
|
||||
);
|
||||
let ascii_per_row: u8 = ascii_per_row
|
||||
.try_into()
|
||||
.expect("`ascii_per_row` should fit in `u8`");
|
||||
let ascii_rows = cmp::max(
|
||||
1,
|
||||
term_h
|
||||
.saturating_sub(8)
|
||||
.div_euclid(u16::from(asc.h).checked_add(1).unwrap()),
|
||||
);
|
||||
let ascii_rows: u8 = ascii_rows
|
||||
.try_into()
|
||||
.expect("`ascii_rows` should fit in `u8`");
|
||||
let (Width(term_w), Height(term_h)) = terminal_size().context("failed to get terminal size")?;
|
||||
let ascii_per_row = (term_w / (asc.w as u16 + 4)).clamp(1, u8::MAX.into()) as u8;
|
||||
let ascii_rows = (term_h.saturating_sub(8) / (asc.h as u16 + 1)).clamp(1, u8::MAX.into()) as u8;
|
||||
(ascii_per_row, ascii_rows)
|
||||
};
|
||||
|
||||
// get distro string and convert it into the enum, neofetch friendly format, so we can check for small logos with the {distro}_small neofetch naming scheme.
|
||||
let tmp_dst = get_distro_name(backend).or_else(|_| get_distro_name(Backend::Neofetch)).context("failed to get distro name")?;
|
||||
let detected_dst = Some(distro.map_or_else(
|
||||
|| {
|
||||
Distro::detect(&tmp_dst)
|
||||
.map_or("".to_string(), |d| format!("{:?}", d).to_lowercase())
|
||||
},
|
||||
|d| d.to_string().to_lowercase(),
|
||||
));
|
||||
|
||||
// in case someone specified {distro}_small already in the --distro arg
|
||||
let detected_dst_small_fmt = if !detected_dst.clone().unwrap().ends_with("_small") {
|
||||
format!("{}_small", detected_dst.unwrap()).to_lowercase()
|
||||
} else {
|
||||
detected_dst.unwrap()
|
||||
};
|
||||
|
||||
let running_dst_sml = if Distro::detect(&detected_dst_small_fmt).is_some() {
|
||||
detected_dst_small_fmt
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
|
||||
|
||||
// load ascii
|
||||
let small_asc = get_distro_ascii(Some(&running_dst_sml), backend).context("failed to get distro ascii")?;
|
||||
let small_asc = small_asc.to_normalized().context("failed to normalize ascii")?;
|
||||
|
||||
let mut asc = asc;
|
||||
let mut logo_chosen: Option<String> = distro.cloned();
|
||||
|
||||
if small_asc.lines != asc.lines && running_dst_sml != "" {
|
||||
let ds_arrangements = [
|
||||
("Default", asc.clone()),
|
||||
("Small", small_asc.clone())
|
||||
];
|
||||
|
||||
let arrangements: IndexMap<Cow<str>, NormalizedAsciiArt> =
|
||||
ds_arrangements.map(|(k, a)| (k.into(), a)).into();
|
||||
|
||||
loop {
|
||||
clear_screen(Some(&title), color_mode, debug_mode).context("failed to clear screen")?;
|
||||
|
||||
let asciis: Vec<Vec<String>> = arrangements
|
||||
.iter()
|
||||
.map(|(k, a)| {
|
||||
let mut v: Vec<String> = a
|
||||
.to_recolored(&ColorAlignment::Horizontal, &color_profile, color_mode, theme)
|
||||
.context("failed to recolor ascii")?
|
||||
.lines;
|
||||
if k == "Small" {
|
||||
// vertical center
|
||||
let pad_len = (asc.h as usize - v.len()) / 2;
|
||||
let mut pad_v: Vec<String> = vec![];
|
||||
for _ in 0..pad_len {
|
||||
pad_v.push("".to_string());
|
||||
}
|
||||
v.splice(0..0, pad_v.clone());
|
||||
v.extend(pad_v);
|
||||
|
||||
let pad_diff = asc.h as usize - v.len();
|
||||
v.extend(std::iter::repeat("".to_string()).take(pad_diff));
|
||||
v.push(format!("{k:^asc_width$}", asc_width = usize::from(small_asc.w)));
|
||||
return Ok(v);
|
||||
}
|
||||
v.push(format!("{k:^asc_width$}", asc_width = usize::from(asc.w)));
|
||||
Ok(v)
|
||||
})
|
||||
.collect::<Result<_>>()?;
|
||||
|
||||
// prints small logo w/ big logo
|
||||
for row in &asciis.into_iter().chunks(usize::from(ascii_per_row)) {
|
||||
|
||||
let row: Vec<Vec<String>> = row.collect();
|
||||
|
||||
for i in 0..usize::from(asc.h).checked_add(1).unwrap() {
|
||||
let mut line = Vec::new();
|
||||
for lines in &row {
|
||||
line.push(&*lines[i]);
|
||||
}
|
||||
printc(line.join(" "), color_mode).context("failed to print ascii line")?;
|
||||
}
|
||||
|
||||
println!();
|
||||
}
|
||||
|
||||
print_title_prompt(option_counter, "Do you want the default logo, or the small logo?");
|
||||
let opts: Vec<Cow<str>> = ["default", "small"].map(Into::into).into();
|
||||
let choice = literal_input("Your choice?", &opts[..], "default", true, color_mode)
|
||||
.context("failed to ask for choice input")
|
||||
.context("failed to select logo type").context("failed to ask for choice input")?;
|
||||
|
||||
if choice.to_lowercase() == "small" {
|
||||
logo_chosen = Some(running_dst_sml);
|
||||
asc = small_asc;
|
||||
}
|
||||
|
||||
update_title(
|
||||
&mut title,
|
||||
&mut option_counter,
|
||||
"Selected logo type",
|
||||
choice.as_ref(),
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// 6. Color arrangement
|
||||
|
||||
let color_align: ColorAlignment;
|
||||
|
||||
// Displays horizontal and vertical arrangements in the first iteration, but
|
||||
// hide them in later iterations
|
||||
let hv_arrangements = [
|
||||
@@ -821,24 +863,16 @@ fn create_config(
|
||||
clear_screen(Some(&title), color_mode, debug_mode).context("failed to clear screen")?;
|
||||
|
||||
// Random color schemes
|
||||
let mut preset_indices: Vec<PresetIndexedColor> =
|
||||
(0..color_profile.unique_colors().colors.len())
|
||||
.map(|pi| u8::try_from(pi).expect("`pi` should fit in `u8`").into())
|
||||
.collect();
|
||||
let mut preset_indices: Vec<PresetIndexedColor> = (0..color_profile.unique_colors().colors.len()).map(|x| (x as u8).into()).collect();
|
||||
while preset_indices.len() < slots.len() {
|
||||
preset_indices.extend_from_within(0..);
|
||||
}
|
||||
let preset_index_permutations: IndexSet<Vec<PresetIndexedColor>> = preset_indices
|
||||
.into_iter()
|
||||
.permutations(slots.len())
|
||||
.take(1000)
|
||||
.collect();
|
||||
let random_count = u16::from(ascii_per_row)
|
||||
.checked_mul(u16::from(ascii_rows))
|
||||
.unwrap()
|
||||
.saturating_sub(u8::try_from(arrangements.len()).unwrap().into());
|
||||
let random_count: u8 = random_count
|
||||
.try_into()
|
||||
.expect("`random_count` should fit in `u8`");
|
||||
let random_count = (ascii_per_row as usize * ascii_rows as usize).saturating_sub(arrangements.len()).clamp(0, u8::MAX.into()) as u8;
|
||||
let choices: IndexSet<Vec<PresetIndexedColor>> =
|
||||
if usize::from(random_count) > preset_index_permutations.len() {
|
||||
preset_index_permutations
|
||||
@@ -885,23 +919,13 @@ fn create_config(
|
||||
for lines in &row {
|
||||
line.push(&*lines[i]);
|
||||
}
|
||||
printc(line.join(" "), color_mode).context("failed to print ascii line")?;
|
||||
printc(line.join(" "), color_mode).context("failed to print ascii line")?;
|
||||
}
|
||||
writeln!(io::stdout()).context("failed to write to stdout")?;
|
||||
println!();
|
||||
}
|
||||
|
||||
print_title_prompt(
|
||||
option_counter,
|
||||
"Let's choose a color arrangement!",
|
||||
color_mode,
|
||||
)
|
||||
.context("failed to print title prompt")?;
|
||||
writeln!(
|
||||
io::stdout(),
|
||||
"You can choose standard horizontal or vertical alignment, or use one of the random \
|
||||
color schemes.\nYou can type \"roll\" to randomize again.\n"
|
||||
)
|
||||
.context("failed to write message to stdout")?;
|
||||
print_title_prompt(option_counter, "Let's choose a color arrangement!");
|
||||
println!("You can choose standard horizontal or vertical alignment, or use one of the random color schemes.\nYou can type \"roll\" to randomize again.\n");
|
||||
let mut opts: Vec<Cow<str>> = ["horizontal", "vertical", "roll"].map(Into::into).into();
|
||||
opts.extend((0..random_count).map(|i| format!("random{i}").into()));
|
||||
let choice = literal_input("Your choice?", &opts[..], "horizontal", true, color_mode)
|
||||
@@ -936,46 +960,31 @@ fn create_config(
|
||||
);
|
||||
|
||||
//////////////////////////////
|
||||
// 6. Select *fetch backend
|
||||
// 7. Select *fetch backend
|
||||
|
||||
let select_backend = || -> Result<Backend> {
|
||||
clear_screen(Some(&title), color_mode, debug_mode).context("failed to clear screen")?;
|
||||
print_title_prompt(option_counter, "Select a *fetch backend", color_mode)
|
||||
.context("failed to print title prompt")?;
|
||||
print_title_prompt(option_counter, "Select a *fetch backend");
|
||||
|
||||
// Check if fastfetch is installed
|
||||
let fastfetch_path = fastfetch_path().ok();
|
||||
|
||||
// Check if macchina is installed
|
||||
#[cfg(feature = "macchina")]
|
||||
let macchina_path = macchina_path().context("failed to get macchina path")?;
|
||||
let macchina_path = macchina_path().unwrap_or(None);
|
||||
|
||||
printc(
|
||||
"- &bneofetch&r: Written in bash, &nbest compatibility&r on Unix systems",
|
||||
color_mode,
|
||||
)
|
||||
.context("failed to print message")?;
|
||||
printc(
|
||||
format!(
|
||||
"- &bfastfetch&r: Written in C, &nbest performance&r {installed_not_installed}",
|
||||
installed_not_installed = fastfetch_path
|
||||
.map(|path| format!("&a(Installed at {path})", path = path.display()))
|
||||
.unwrap_or_else(|| "&c(Not installed)".to_owned())
|
||||
),
|
||||
color_mode,
|
||||
)
|
||||
.context("failed to print message")?;
|
||||
printc!("- &bneofetch&r: Written in bash, &nbest compatibility&r on Unix systems");
|
||||
printc!("- &bfastfetch&r: Written in C, &nbest performance&r {}",
|
||||
fastfetch_path
|
||||
.map(|path| format!("&a(Installed at {path})", path = path.display()))
|
||||
.unwrap_or_else(|| "&c(Not installed)".to_owned())
|
||||
);
|
||||
#[cfg(feature = "macchina")]
|
||||
printc(
|
||||
format!(
|
||||
"- &bmacchina&r: Written in Rust, &nbest performance&r {installed_not_installed}\n",
|
||||
installed_not_installed = macchina_path
|
||||
.map(|path| format!("&a(Installed at {path})", path = path.display()))
|
||||
.unwrap_or_else(|| "&c(Not installed)".to_owned())
|
||||
),
|
||||
color_mode,
|
||||
)
|
||||
.context("failed to print message")?;
|
||||
printc!("- &bmacchina&r: Written in Rust, &nbest performance&r {}\n",
|
||||
macchina_path
|
||||
.map(|path| format!("&a(Installed at {path})", path = path.display()))
|
||||
.unwrap_or_else(|| "&c(Not installed)".to_owned())
|
||||
);
|
||||
|
||||
let choice = literal_input(
|
||||
"Your choice?",
|
||||
@@ -996,18 +1005,66 @@ fn create_config(
|
||||
backend.as_ref(),
|
||||
);
|
||||
|
||||
//////////////////////////////
|
||||
// 8. Custom ASCII file
|
||||
let mut custom_ascii_path: Option<String> = None;
|
||||
clear_screen(Some(&title), color_mode, debug_mode).context("failed to clear screen")?;
|
||||
let choice = literal_input(
|
||||
"Do you want to specify a custom ASCII file?",
|
||||
&["y", "n"],
|
||||
"n",
|
||||
true,
|
||||
color_mode,
|
||||
)
|
||||
.context("failed to ask for choice input")?;
|
||||
|
||||
if choice == "y" {
|
||||
loop {
|
||||
let pth = input(Some("Path to custom ASCII file (must be UTF-8 encoded, empty to skip): "))?.trim().to_owned();
|
||||
if pth.is_empty() {
|
||||
printc!("&cNo path entered. Skipping custom ASCII file.");
|
||||
break;
|
||||
}
|
||||
|
||||
let pth_buf = PathBuf::from(&pth);
|
||||
if !pth_buf.is_file() {
|
||||
printc!("&cError: File not found at {pth}");
|
||||
continue;
|
||||
}
|
||||
|
||||
match fs::read_to_string(&pth_buf) {
|
||||
Ok(_) => {
|
||||
custom_ascii_path = Some(pth);
|
||||
update_title(
|
||||
&mut title,
|
||||
&mut option_counter,
|
||||
"Custom ASCII file",
|
||||
custom_ascii_path.as_ref().unwrap(),
|
||||
);
|
||||
break;
|
||||
}
|
||||
Err(e) => {
|
||||
printc!("&cError: File is not UTF-8 encoded or an unexpected error occurred: {e}");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create config
|
||||
clear_screen(Some(&title), color_mode, debug_mode).context("failed to clear screen")?;
|
||||
let config = Config {
|
||||
preset,
|
||||
preset: preset.as_ref().to_string(),
|
||||
mode: color_mode,
|
||||
light_dark: theme,
|
||||
light_dark: Some(theme),
|
||||
auto_detect_light_dark: Some(det_bg.is_some()),
|
||||
lightness: Some(lightness),
|
||||
color_align,
|
||||
backend,
|
||||
args: None,
|
||||
distro: distro.cloned(),
|
||||
distro: logo_chosen,
|
||||
pride_month_disable: false,
|
||||
custom_ascii_path,
|
||||
};
|
||||
debug!(?config, "created config");
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ use bpaf::ShellComp;
|
||||
use bpaf::{construct, long, OptionParser, Parser as _};
|
||||
use directories::BaseDirs;
|
||||
use itertools::Itertools as _;
|
||||
use strum::{VariantArray, VariantNames};
|
||||
use strum::VariantNames;
|
||||
|
||||
use crate::color_util::{color, Lightness};
|
||||
use crate::presets::Preset;
|
||||
@@ -18,7 +18,7 @@ use crate::types::{AnsiMode, Backend};
|
||||
pub struct Options {
|
||||
pub config: bool,
|
||||
pub config_file: PathBuf,
|
||||
pub preset: Option<Preset>,
|
||||
pub preset: Option<String>,
|
||||
pub mode: Option<AnsiMode>,
|
||||
pub backend: Option<Backend>,
|
||||
pub args: Option<Vec<String>>,
|
||||
@@ -31,6 +31,7 @@ pub struct Options {
|
||||
pub print_font_logo: bool,
|
||||
pub test_print: bool,
|
||||
pub ask_exit: bool,
|
||||
pub auto_detect_light_dark: Option<bool>,
|
||||
}
|
||||
|
||||
pub fn options() -> OptionParser<Options> {
|
||||
@@ -54,7 +55,7 @@ pub fn options() -> OptionParser<Options> {
|
||||
let preset = long("preset")
|
||||
.short('p')
|
||||
.help(&*format!(
|
||||
"Use preset
|
||||
"Use preset or comma-separated color list or comma-separated hex colors (e.g., \"#ff0000,#00ff00,#0000ff\")
|
||||
PRESET={{{presets}}}",
|
||||
presets = <Preset as VariantNames>::VARIANTS
|
||||
.iter()
|
||||
@@ -64,30 +65,7 @@ PRESET={{{presets}}}",
|
||||
.argument::<String>("PRESET");
|
||||
#[cfg(feature = "autocomplete")]
|
||||
let preset = preset.complete(complete_preset);
|
||||
let preset = preset
|
||||
.parse(|s| {
|
||||
Preset::from_str(&s)
|
||||
.or_else(|e| {
|
||||
if s == "random" {
|
||||
let mut rng = fastrand::Rng::new();
|
||||
Ok(*rng
|
||||
.choice(<Preset as VariantArray>::VARIANTS)
|
||||
.expect("preset iterator should not be empty"))
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
})
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"PRESET should be one of {{{presets}}}",
|
||||
presets = <Preset as VariantNames>::VARIANTS
|
||||
.iter()
|
||||
.chain(iter::once(&"random"))
|
||||
.join(",")
|
||||
)
|
||||
})
|
||||
})
|
||||
.optional();
|
||||
let preset = preset.optional();
|
||||
let mode = long("mode")
|
||||
.short('m')
|
||||
.help(&*format!(
|
||||
@@ -170,6 +148,10 @@ BACKEND={{{backends}}}",
|
||||
.help("Ask for input before exiting")
|
||||
.switch()
|
||||
.hide();
|
||||
let auto_detect_light_dark = long("auto-detect-light-dark")
|
||||
.help("Enables hyfetch to detect light/dark terminal background in runtime")
|
||||
.argument("BOOL")
|
||||
.optional();
|
||||
|
||||
construct!(Options {
|
||||
config,
|
||||
@@ -188,6 +170,7 @@ BACKEND={{{backends}}}",
|
||||
// hidden
|
||||
test_print,
|
||||
ask_exit,
|
||||
auto_detect_light_dark,
|
||||
})
|
||||
.to_options()
|
||||
.header(
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
use std::iter;
|
||||
use std::num::{NonZeroU8, NonZeroUsize};
|
||||
|
||||
use anyhow::{anyhow, Result, Context as _};
|
||||
use indexmap::IndexSet;
|
||||
use palette::num::ClampAssign as _;
|
||||
use palette::{IntoColorMut as _, LinSrgb, Okhsl, Srgb};
|
||||
use tracing::debug;
|
||||
use unicode_segmentation::UnicodeSegmentation as _;
|
||||
|
||||
use crate::color_util::{ForegroundBackground, Lightness, ToAnsiString as _};
|
||||
use crate::types::{AnsiMode, TerminalTheme};
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||
pub struct ColorProfile {
|
||||
pub colors: Vec<Srgb<u8>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub enum AssignLightness {
|
||||
Replace(Lightness),
|
||||
ClampMax(Lightness),
|
||||
ClampMin(Lightness),
|
||||
}
|
||||
|
||||
impl ColorProfile {
|
||||
pub fn new(colors: Vec<Srgb<u8>>) -> Self {
|
||||
Self { colors }
|
||||
}
|
||||
|
||||
pub fn from_hex_colors<S>(hex_colors: Vec<S>) -> Result<Self>
|
||||
where
|
||||
S: AsRef<str>,
|
||||
{
|
||||
let colors = hex_colors
|
||||
.into_iter()
|
||||
.map(|s| s.as_ref().parse())
|
||||
.collect::<Result<_, _>>()
|
||||
.context("failed to parse hex colors")?;
|
||||
Ok(Self::new(colors))
|
||||
}
|
||||
|
||||
/// Maps colors based on weights.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `weights` - Weights of each color (`weights[i]` = how many times
|
||||
/// `colors[i]` appears)
|
||||
pub fn with_weights(&self, weights: Vec<u8>) -> Result<Self> {
|
||||
if weights.len() != self.colors.len() {
|
||||
debug!(?weights, ?self.colors, "length mismatch between `weights` and `colors`");
|
||||
return Err(anyhow!(
|
||||
"`weights` should have the same number of elements as `colors`"
|
||||
));
|
||||
}
|
||||
|
||||
let mut weighted_colors = Vec::new();
|
||||
|
||||
for (i, w) in weights.into_iter().enumerate() {
|
||||
weighted_colors.extend(iter::repeat(self.colors[i]).take(usize::from(w)));
|
||||
}
|
||||
|
||||
Ok(Self::new(weighted_colors))
|
||||
}
|
||||
|
||||
/// Creates a new color profile, with the colors spread to the specified
|
||||
/// length.
|
||||
pub fn with_length(&self, length: NonZeroU8) -> Result<Self> {
|
||||
let orig_len = self.colors.len();
|
||||
let orig_len: NonZeroUsize = orig_len.try_into().expect("`colors` should not be empty");
|
||||
let orig_len: NonZeroU8 = orig_len
|
||||
.try_into()
|
||||
.expect("`colors` should not have more than 255 elements");
|
||||
// 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 = usize::from(orig_len.get() / 2);
|
||||
|
||||
// How many copies of each color should be displayed at least?
|
||||
let repeats = length.get().div_euclid(orig_len.get());
|
||||
let mut weights = vec![repeats; NonZeroUsize::from(orig_len).get()];
|
||||
|
||||
// How many extra spaces left?
|
||||
let mut extras = length.get().rem_euclid(orig_len.get());
|
||||
|
||||
// If there is an odd space left, extend the center by one space
|
||||
if extras % 2 == 1 {
|
||||
weights[center_i] = weights[center_i].checked_add(1).unwrap();
|
||||
extras = extras.checked_sub(1).unwrap();
|
||||
}
|
||||
|
||||
// Add weight to border until there's no space left (extras must be even at this
|
||||
// point)
|
||||
let weights_len = weights.len();
|
||||
for border_i in 0..usize::from(extras / 2) {
|
||||
weights[border_i] = weights[border_i].checked_add(1).unwrap();
|
||||
let border_opp = weights_len
|
||||
.checked_sub(border_i)
|
||||
.unwrap()
|
||||
.checked_sub(1)
|
||||
.unwrap();
|
||||
weights[border_opp] = weights[border_opp].checked_add(1).unwrap();
|
||||
}
|
||||
|
||||
self.with_weights(weights)
|
||||
}
|
||||
|
||||
/// Colors a text.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `foreground_background` - Whether the color is shown on the foreground
|
||||
/// text or the background block
|
||||
/// * `space_only` - Whether to only color spaces
|
||||
pub fn color_text<S>(
|
||||
&self,
|
||||
txt: S,
|
||||
color_mode: AnsiMode,
|
||||
foreground_background: ForegroundBackground,
|
||||
space_only: bool,
|
||||
) -> Result<String>
|
||||
where
|
||||
S: AsRef<str>,
|
||||
{
|
||||
let txt = txt.as_ref();
|
||||
|
||||
let txt: Vec<&str> = txt.graphemes(true).collect();
|
||||
|
||||
let ColorProfile { colors } = {
|
||||
let length = txt.len();
|
||||
let length: NonZeroUsize = length.try_into().context("`txt` should not be empty")?;
|
||||
let length: NonZeroU8 = length.try_into().with_context(|| {
|
||||
format!(
|
||||
"`txt` should not have more than {limit} characters",
|
||||
limit = u8::MAX
|
||||
)
|
||||
})?;
|
||||
self.with_length(length)
|
||||
.with_context(|| format!("failed to spread color profile to length {length}"))?
|
||||
};
|
||||
|
||||
let mut buf = String::new();
|
||||
for (i, &gr) in txt.iter().enumerate() {
|
||||
if space_only && gr != " " {
|
||||
if i > 0 && txt[i.checked_sub(1).unwrap()] == " " {
|
||||
buf.push_str("\x1b[39;49m");
|
||||
}
|
||||
buf.push_str(gr);
|
||||
} else {
|
||||
buf.push_str(&colors[i].to_ansi_string(color_mode, foreground_background));
|
||||
buf.push_str(gr);
|
||||
}
|
||||
}
|
||||
|
||||
buf.push_str("\x1b[39;49m");
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
/// Creates a new color profile, with the colors lightened by a multiplier.
|
||||
pub fn lighten(&self, multiplier: f32) -> Self {
|
||||
let mut rgb_f32_colors: Vec<LinSrgb> =
|
||||
self.colors.iter().map(|c| c.into_linear()).collect();
|
||||
|
||||
{
|
||||
let okhsl_f32_colors: &mut [Okhsl] = &mut rgb_f32_colors.into_color_mut();
|
||||
|
||||
for okhsl_f32_color in okhsl_f32_colors {
|
||||
okhsl_f32_color.lightness *= multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
let rgb_u8_colors: Vec<_> = rgb_f32_colors
|
||||
.into_iter()
|
||||
.map(Srgb::<u8>::from_linear)
|
||||
.collect();
|
||||
|
||||
Self {
|
||||
colors: rgb_u8_colors,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new color profile, with the colors set to the specified
|
||||
/// [`Okhsl`] lightness value.
|
||||
pub fn with_lightness(&self, assign_lightness: AssignLightness) -> Self {
|
||||
let mut rgb_f32_colors: Vec<LinSrgb> =
|
||||
self.colors.iter().map(|c| c.into_linear()).collect();
|
||||
|
||||
{
|
||||
let okhsl_f32_colors: &mut [Okhsl] = &mut rgb_f32_colors.into_color_mut();
|
||||
|
||||
for okhsl_f32_color in okhsl_f32_colors {
|
||||
match assign_lightness {
|
||||
AssignLightness::Replace(lightness) => {
|
||||
okhsl_f32_color.lightness = lightness.into();
|
||||
},
|
||||
AssignLightness::ClampMax(lightness) => {
|
||||
okhsl_f32_color.lightness.clamp_max_assign(lightness.into());
|
||||
},
|
||||
AssignLightness::ClampMin(lightness) => {
|
||||
okhsl_f32_color.lightness.clamp_min_assign(lightness.into());
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let rgb_u8_colors: Vec<Srgb<u8>> = rgb_f32_colors
|
||||
.into_iter()
|
||||
.map(Srgb::<u8>::from_linear)
|
||||
.collect();
|
||||
|
||||
Self {
|
||||
colors: rgb_u8_colors,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new color profile, with the colors set to the specified
|
||||
/// [`Okhsl`] lightness value, adapted to the terminal theme.
|
||||
pub fn with_lightness_adaptive(&self, lightness: Lightness, theme: TerminalTheme) -> Self {
|
||||
match theme {
|
||||
TerminalTheme::Dark => self.with_lightness(AssignLightness::ClampMin(lightness)),
|
||||
TerminalTheme::Light => self.with_lightness(AssignLightness::ClampMax(lightness)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates another color profile with only the unique colors.
|
||||
pub fn unique_colors(&self) -> Self {
|
||||
let unique_colors: IndexSet<[u8; 3]> = self.colors.iter().map(|&c| c.into()).collect();
|
||||
let unique_colors: Vec<Srgb<u8>> = unique_colors.into_iter().map(|c| c.into()).collect();
|
||||
Self::new(unique_colors)
|
||||
}
|
||||
}
|
||||
@@ -403,18 +403,20 @@ where
|
||||
Ok(dst)
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! printc {
|
||||
($($arg:tt)*) => {
|
||||
println!("{}", color(format!("{}&r", format!($($arg)*)), AnsiMode::Rgb).expect("failed to color message"));
|
||||
};
|
||||
}
|
||||
|
||||
/// Prints with color.
|
||||
pub fn printc<S>(msg: S, mode: AnsiMode) -> Result<()>
|
||||
where
|
||||
S: AsRef<str>,
|
||||
{
|
||||
writeln!(
|
||||
io::stdout(),
|
||||
"{msg}",
|
||||
msg = color(format!("{msg}&r", msg = msg.as_ref()), mode)
|
||||
.context("failed to color message")?
|
||||
)
|
||||
.context("failed to write message to stdout")
|
||||
println!("{msg}", msg = color(format!("{msg}&r", msg = msg.as_ref()), mode).context("failed to color message")?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Clears screen using ANSI escape codes.
|
||||
|
||||
@@ -3,10 +3,10 @@ use crate::types::Backend;
|
||||
use crate::utils::get_cache_path;
|
||||
use anyhow::{Context, Result};
|
||||
use std::collections::HashMap;
|
||||
use std::fs::{self, File};
|
||||
use std::fs::{File};
|
||||
use std::io::{Read, Write};
|
||||
|
||||
const FONT_LOGOS: &str = include_str!("../../../hyfetch/data/font_logos.json");
|
||||
const FONT_LOGOS: &str = include_str!(concat!(env!("OUT_DIR"), "/hyfetch/data/font_logos.json"));
|
||||
|
||||
pub fn get_font_logo(backend: Backend) -> Result<String> {
|
||||
// Check if the cache file exists and return its contents if it does
|
||||
@@ -34,11 +34,6 @@ pub fn get_font_logo(backend: Backend) -> Result<String> {
|
||||
|
||||
let logo = font_logos.get(matched_distro).unwrap();
|
||||
|
||||
// Create parent directories for the cache if they don't exist
|
||||
if let Some(parent) = cache_path.parent() {
|
||||
fs::create_dir_all(parent).context("Failed to create cache directory")?;
|
||||
}
|
||||
|
||||
// Write the logo to the cache file
|
||||
let mut cache_file = File::create(cache_path).context("Failed to create cache file")?;
|
||||
cache_file.write_all(logo.as_bytes()).context("Failed to write logo to cache file")?;
|
||||
|
||||
@@ -9,3 +9,4 @@ pub mod presets;
|
||||
pub mod pride_month;
|
||||
pub mod types;
|
||||
pub mod utils;
|
||||
pub mod color_profile;
|
||||
|
||||
@@ -2,14 +2,14 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::color_util::Lightness;
|
||||
use crate::neofetch_util::ColorAlignment;
|
||||
use crate::presets::Preset;
|
||||
use crate::types::{AnsiMode, Backend, TerminalTheme};
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct Config {
|
||||
pub preset: Preset,
|
||||
pub preset: String,
|
||||
pub mode: AnsiMode,
|
||||
pub light_dark: TerminalTheme,
|
||||
pub auto_detect_light_dark: Option<bool>,
|
||||
pub light_dark: Option<TerminalTheme>,
|
||||
pub lightness: Option<Lightness>,
|
||||
pub color_align: ColorAlignment,
|
||||
pub backend: Backend,
|
||||
@@ -18,6 +18,7 @@ pub struct Config {
|
||||
pub args: Option<Vec<String>>,
|
||||
pub distro: Option<String>,
|
||||
pub pride_month_disable: bool,
|
||||
pub custom_ascii_path: Option<String>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
@@ -31,11 +32,6 @@ impl Config {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lightness(&self) -> Lightness {
|
||||
self.lightness
|
||||
.unwrap_or_else(|| Self::default_lightness(self.light_dark))
|
||||
}
|
||||
}
|
||||
|
||||
mod args_serde {
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ffi::OsStr;
|
||||
#[cfg(feature = "macchina")]
|
||||
use std::fs;
|
||||
use std::io::{self, Write as _};
|
||||
use std::path::{PathBuf};
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::sync::OnceLock;
|
||||
use std::{env, fmt};
|
||||
@@ -53,7 +53,7 @@ _/\_\_ _/_/\_
|
||||
pub const NEOFETCH_COLOR_PATTERNS: [&str; 6] =
|
||||
["${c1}", "${c2}", "${c3}", "${c4}", "${c5}", "${c6}"];
|
||||
pub static NEOFETCH_COLORS_AC: OnceLock<AhoCorasick> = OnceLock::new();
|
||||
pub const NEOFETCH_SCRIPT: &str = include_str!("../../../neofetch");
|
||||
pub const NEOFETCH_SCRIPT: &str = include_str!(concat!(env!("OUT_DIR"), "/neofetch"));
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Debug, AsRefStr, Deserialize, Serialize)]
|
||||
#[serde(tag = "mode")]
|
||||
@@ -113,16 +113,12 @@ where
|
||||
};
|
||||
|
||||
if let Some(selected) = find_selection(&selection, options) {
|
||||
writeln!(io::stdout()).context("failed to write to stdout")?;
|
||||
println!();
|
||||
|
||||
return Ok(selected);
|
||||
} else {
|
||||
let options_text = options.iter().map(AsRef::as_ref).join("|");
|
||||
writeln!(
|
||||
io::stdout(),
|
||||
"Invalid selection! {selection} is not one of {options_text}"
|
||||
)
|
||||
.context("failed to write message to stdout")?;
|
||||
println!("Invalid selection! {selection} is not one of {options_text}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,7 +281,7 @@ pub fn run(asc: RecoloredAsciiArt, backend: Backend, args: Option<&Vec<String>>)
|
||||
}
|
||||
|
||||
/// Gets distro ascii width and height, ignoring color code.
|
||||
pub fn ascii_size<S>(asc: S) -> Result<(u8, u8)>
|
||||
pub fn ascii_size<S>(asc: S) -> Result<(u16, u16)>
|
||||
where
|
||||
S: AsRef<str>,
|
||||
{
|
||||
@@ -307,25 +303,11 @@ where
|
||||
return Ok((0, 0));
|
||||
}
|
||||
|
||||
let width = asc
|
||||
.lines()
|
||||
.map(|line| line.graphemes(true).count())
|
||||
.max()
|
||||
let width = asc.lines()
|
||||
.map(|line| line.graphemes(true).count()).max()
|
||||
.expect("line iterator should not be empty");
|
||||
let width: u8 = width.try_into().with_context(|| {
|
||||
format!(
|
||||
"`asc` should not have more than {limit} characters per line",
|
||||
limit = u8::MAX
|
||||
)
|
||||
})?;
|
||||
let height = asc.lines().count();
|
||||
let height: u8 = height.try_into().with_context(|| {
|
||||
format!(
|
||||
"`asc` should not have more than {limit} lines",
|
||||
limit = u8::MAX
|
||||
)
|
||||
})?;
|
||||
|
||||
let width: u16 = width.try_into().context("ascii art width should fit in u16")?;
|
||||
let height: u16 = asc.lines().count().try_into().context("ascii art height should fit in u16")?;
|
||||
Ok((width, height))
|
||||
}
|
||||
|
||||
@@ -438,6 +420,7 @@ where
|
||||
debug!(?ff_path, "fastfetch path");
|
||||
|
||||
let mut command = Command::new(ff_path);
|
||||
command.env("FFTS_IGNORE_PARENT", "1");
|
||||
command.args(args);
|
||||
Ok(command)
|
||||
}
|
||||
@@ -481,20 +464,12 @@ where
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug")]
|
||||
pub(crate) fn get_distro_name(backend: Backend) -> Result<String> {
|
||||
pub fn get_distro_name(backend: Backend) -> Result<String> {
|
||||
match backend {
|
||||
Backend::Neofetch => run_neofetch_command_piped(&["ascii_distro_name"])
|
||||
.context("failed to get distro name from neofetch"),
|
||||
Backend::Fastfetch => run_fastfetch_command_piped(&[
|
||||
"--logo",
|
||||
"none",
|
||||
"-s",
|
||||
"OS",
|
||||
"--disable-linewrap",
|
||||
"--os-key",
|
||||
" ",
|
||||
])
|
||||
.context("failed to get distro name from fastfetch"),
|
||||
Backend::Fastfetch => Ok(run_fastfetch_command_piped(&["--logo", "none", "-c", "none", "-s", "OS",])
|
||||
.context("failed to get distro name from fastfetch")?.replace("OS: ", "")),
|
||||
#[cfg(feature = "macchina")]
|
||||
Backend::Macchina => {
|
||||
// Write ascii art to temp file
|
||||
|
||||
@@ -1,846 +1,3 @@
|
||||
use std::iter;
|
||||
use std::num::{NonZeroU8, NonZeroUsize};
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use anyhow::{anyhow, Context as _, Result};
|
||||
use indexmap::IndexSet;
|
||||
use palette::num::ClampAssign as _;
|
||||
use palette::{IntoColorMut as _, LinSrgb, Okhsl, Srgb};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum::{AsRefStr, EnumCount, EnumString, VariantArray, VariantNames};
|
||||
use tracing::debug;
|
||||
use unicode_segmentation::UnicodeSegmentation as _;
|
||||
|
||||
use crate::color_util::{ForegroundBackground, Lightness, ToAnsiString as _};
|
||||
use crate::types::{AnsiMode, TerminalTheme};
|
||||
|
||||
#[derive(
|
||||
Copy,
|
||||
Clone,
|
||||
Hash,
|
||||
Debug,
|
||||
AsRefStr,
|
||||
Deserialize,
|
||||
EnumCount,
|
||||
EnumString,
|
||||
Serialize,
|
||||
VariantArray,
|
||||
VariantNames,
|
||||
)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
#[strum(serialize_all = "kebab-case")]
|
||||
pub enum Preset {
|
||||
Rainbow,
|
||||
|
||||
Transgender,
|
||||
|
||||
Nonbinary,
|
||||
|
||||
Xenogender,
|
||||
|
||||
Agender,
|
||||
|
||||
Queer,
|
||||
|
||||
Genderfluid,
|
||||
|
||||
Bisexual,
|
||||
|
||||
Pansexual,
|
||||
|
||||
Polysexual,
|
||||
|
||||
Omnisexual,
|
||||
|
||||
Omniromantic,
|
||||
|
||||
GayMen,
|
||||
|
||||
Lesbian,
|
||||
|
||||
Abrosexual,
|
||||
|
||||
Asexual,
|
||||
|
||||
Aromantic,
|
||||
|
||||
Aroace1,
|
||||
|
||||
Aroace2,
|
||||
|
||||
Aroace3,
|
||||
|
||||
Greysexual,
|
||||
|
||||
Autosexual,
|
||||
|
||||
Intergender,
|
||||
|
||||
Greygender,
|
||||
|
||||
Akiosexual,
|
||||
|
||||
Bigender,
|
||||
|
||||
Demigender,
|
||||
|
||||
Demiboy,
|
||||
|
||||
Demigirl,
|
||||
|
||||
Transmasculine,
|
||||
|
||||
Transfeminine,
|
||||
|
||||
Genderfaun,
|
||||
|
||||
Demifaun,
|
||||
|
||||
Genderfae,
|
||||
|
||||
Demifae,
|
||||
|
||||
Neutrois,
|
||||
|
||||
Biromantic1,
|
||||
|
||||
Autoromantic,
|
||||
|
||||
Boyflux2,
|
||||
|
||||
Girlflux,
|
||||
|
||||
Genderflux,
|
||||
|
||||
Finsexual,
|
||||
|
||||
Unlabeled1,
|
||||
|
||||
Unlabeled2,
|
||||
|
||||
Pangender,
|
||||
|
||||
/// High-contrast version of pangender flag
|
||||
#[serde(rename = "pangender.contrast")]
|
||||
#[strum(serialize = "pangender.contrast")]
|
||||
PangenderContrast,
|
||||
|
||||
#[serde(rename = "gendernonconforming1")]
|
||||
#[strum(serialize = "gendernonconforming1")]
|
||||
GenderNonconforming1,
|
||||
|
||||
#[serde(rename = "gendernonconforming2")]
|
||||
#[strum(serialize = "gendernonconforming2")]
|
||||
GenderNonconforming2,
|
||||
|
||||
Femboy,
|
||||
|
||||
Tomboy,
|
||||
|
||||
Gynesexual,
|
||||
|
||||
Androsexual,
|
||||
|
||||
Gendervoid,
|
||||
|
||||
Voidgirl,
|
||||
|
||||
Voidboy,
|
||||
|
||||
NonhumanUnity,
|
||||
|
||||
/// For all the dogs
|
||||
Caninekin,
|
||||
|
||||
Plural,
|
||||
|
||||
Fraysexual,
|
||||
|
||||
Bear,
|
||||
|
||||
Butch,
|
||||
|
||||
Leather,
|
||||
|
||||
Otter,
|
||||
|
||||
Twink,
|
||||
|
||||
Kenochoric,
|
||||
|
||||
Veldian,
|
||||
|
||||
Solian,
|
||||
|
||||
Lunian,
|
||||
|
||||
Polyam,
|
||||
|
||||
Sapphic,
|
||||
|
||||
Androgyne,
|
||||
|
||||
Interprogress,
|
||||
|
||||
Progress,
|
||||
|
||||
Intersex,
|
||||
|
||||
OldPolyam,
|
||||
|
||||
EqualRights,
|
||||
|
||||
Drag,
|
||||
|
||||
Pronounfluid,
|
||||
|
||||
Pronounflux,
|
||||
|
||||
Exipronoun,
|
||||
|
||||
Neopronoun,
|
||||
|
||||
Neofluid,
|
||||
|
||||
Genderqueer,
|
||||
|
||||
/// Meme flag
|
||||
Beiyang,
|
||||
|
||||
/// Meme flag
|
||||
Burger,
|
||||
|
||||
/// Meme flag
|
||||
#[serde(rename = "throatlozenges")]
|
||||
#[strum(serialize = "throatlozenges")]
|
||||
ThroatLozenges,
|
||||
|
||||
/// Colors from Gilbert Baker's original 1978 flag design
|
||||
Baker,
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||
pub struct ColorProfile {
|
||||
pub colors: Vec<Srgb<u8>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub enum AssignLightness {
|
||||
Replace(Lightness),
|
||||
ClampMax(Lightness),
|
||||
ClampMin(Lightness),
|
||||
}
|
||||
|
||||
impl Preset {
|
||||
pub fn color_profile(&self) -> ColorProfile {
|
||||
(match self {
|
||||
Self::Rainbow => ColorProfile::from_hex_colors(vec![
|
||||
"#E50000", "#FF8D00", "#FFEE00", "#028121", "#004CFF", "#770088",
|
||||
]),
|
||||
|
||||
Self::Transgender => ColorProfile::from_hex_colors(vec![
|
||||
"#55CDFD", "#F6AAB7", "#FFFFFF", "#F6AAB7", "#55CDFD",
|
||||
]),
|
||||
|
||||
Self::Nonbinary => {
|
||||
ColorProfile::from_hex_colors(vec!["#FCF431", "#FCFCFC", "#9D59D2", "#282828"])
|
||||
},
|
||||
|
||||
// sourced from https://commons.wikimedia.org/wiki/File:Xenogender_pride_flag.svg
|
||||
Self::Xenogender => ColorProfile::from_hex_colors(vec![
|
||||
"#FF6692", "#FF9A98", "#FFB883", "#FBFFA8", "#85BCFF", "#9D85FF", "#A510FF",
|
||||
]),
|
||||
|
||||
Self::Agender => ColorProfile::from_hex_colors(vec![
|
||||
"#000000", "#BABABA", "#FFFFFF", "#BAF484", "#FFFFFF", "#BABABA", "#000000",
|
||||
]),
|
||||
|
||||
Self::Queer => ColorProfile::from_hex_colors(vec!["#B57FDD", "#FFFFFF", "#49821E"]),
|
||||
|
||||
Self::Genderfluid => ColorProfile::from_hex_colors(vec![
|
||||
"#FE76A2", "#FFFFFF", "#BF12D7", "#000000", "#303CBE",
|
||||
]),
|
||||
|
||||
Self::Bisexual => ColorProfile::from_hex_colors(vec!["#D60270", "#9B4F96", "#0038A8"]),
|
||||
|
||||
Self::Pansexual => ColorProfile::from_hex_colors(vec!["#FF1C8D", "#FFD700", "#1AB3FF"]),
|
||||
|
||||
Self::Polysexual => {
|
||||
ColorProfile::from_hex_colors(vec!["#F714BA", "#01D66A", "#1594F6"])
|
||||
},
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/omnisexual
|
||||
Self::Omnisexual => ColorProfile::from_hex_colors(vec![
|
||||
"#FE9ACE", "#FF53BF", "#200044", "#6760FE", "#8EA6FF",
|
||||
]),
|
||||
|
||||
Self::Omniromantic => ColorProfile::from_hex_colors(vec![
|
||||
"#FEC8E4", "#FDA1DB", "#89739A", "#ABA7FE", "#BFCEFF",
|
||||
]),
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/gay-men
|
||||
Self::GayMen => ColorProfile::from_hex_colors(vec![
|
||||
"#078D70", "#98E8C1", "#FFFFFF", "#7BADE2", "#3D1A78",
|
||||
]),
|
||||
|
||||
Self::Lesbian => ColorProfile::from_hex_colors(vec![
|
||||
"#D62800", "#FF9B56", "#FFFFFF", "#D462A6", "#A40062",
|
||||
]),
|
||||
|
||||
// used colorpicker to source from https://fyeahaltpride.tumblr.com/post/151704251345/could-you-guys-possibly-make-an-abrosexual-pride
|
||||
Self::Abrosexual => ColorProfile::from_hex_colors(vec![
|
||||
"#46D294", "#A3E9CA", "#FFFFFF", "#F78BB3", "#EE1766",
|
||||
]),
|
||||
|
||||
Self::Asexual => {
|
||||
ColorProfile::from_hex_colors(vec!["#000000", "#A4A4A4", "#FFFFFF", "#810081"])
|
||||
},
|
||||
|
||||
Self::Aromantic => ColorProfile::from_hex_colors(vec![
|
||||
"#3BA740", "#A8D47A", "#FFFFFF", "#ABABAB", "#000000",
|
||||
]),
|
||||
|
||||
// sourced from https://flag.library.lgbt/flags/aroace/
|
||||
Self::Aroace1 => ColorProfile::from_hex_colors(vec![
|
||||
"#E28C00", "#ECCD00", "#FFFFFF", "#62AEDC", "#203856",
|
||||
]),
|
||||
|
||||
// sourced from https://flag.library.lgbt/flags/aroace/
|
||||
Self::Aroace2 => ColorProfile::from_hex_colors(vec![
|
||||
"#000000", "#810081", "#A4A4A4", "#FFFFFF", "#A8D47A", "#3BA740",
|
||||
]),
|
||||
|
||||
// sourced from https://flag.library.lgbt/flags/aroace/
|
||||
Self::Aroace3 => ColorProfile::from_hex_colors(vec![
|
||||
"#3BA740", "#A8D47A", "#FFFFFF", "#ABABAB", "#000000", "#A4A4A4", "#FFFFFF",
|
||||
"#810081",
|
||||
]),
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/greysexual
|
||||
Self::Greysexual => ColorProfile::from_hex_colors(vec![
|
||||
"#740194", "#AEB1AA", "#FFFFFF", "#AEB1AA", "#740194",
|
||||
]),
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/autosexual
|
||||
Self::Autosexual => ColorProfile::from_hex_colors(vec!["#99D9EA", "#7F7F7F"]),
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/intergender
|
||||
Self::Intergender => {
|
||||
ColorProfile::from_hex_colors(vec!["#900DC2", "#FFE54F", "#900DC2"])
|
||||
.and_then(|c| c.with_weights(vec![2, 1, 2]))
|
||||
},
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/greygender
|
||||
Self::Greygender => ColorProfile::from_hex_colors(vec![
|
||||
"#B3B3B3", "#FFFFFF", "#062383", "#FFFFFF", "#535353",
|
||||
])
|
||||
.and_then(|c| c.with_weights(vec![2, 1, 2, 1, 2])),
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/akiosexual
|
||||
Self::Akiosexual => ColorProfile::from_hex_colors(vec![
|
||||
"#F9485E", "#FEA06A", "#FEF44C", "#FFFFFF", "#000000",
|
||||
]),
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/bigender
|
||||
Self::Bigender => ColorProfile::from_hex_colors(vec![
|
||||
"#C479A2", "#EDA5CD", "#D6C7E8", "#FFFFFF", "#D6C7E8", "#9AC7E8", "#6D82D1",
|
||||
]),
|
||||
|
||||
// yellow sourced from https://lgbtqia.fandom.com/f/p/4400000000000041031
|
||||
// other colors sourced from demiboy and demigirl flags
|
||||
Self::Demigender => ColorProfile::from_hex_colors(vec![
|
||||
"#7F7F7F", "#C4C4C4", "#FBFF75", "#FFFFFF", "#FBFF75", "#C4C4C4", "#7F7F7F",
|
||||
]),
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/demiboy
|
||||
Self::Demiboy => ColorProfile::from_hex_colors(vec![
|
||||
"#7F7F7F", "#C4C4C4", "#9DD7EA", "#FFFFFF", "#9DD7EA", "#C4C4C4", "#7F7F7F",
|
||||
]),
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/demigirl
|
||||
Self::Demigirl => ColorProfile::from_hex_colors(vec![
|
||||
"#7F7F7F", "#C4C4C4", "#FDADC8", "#FFFFFF", "#FDADC8", "#C4C4C4", "#7F7F7F",
|
||||
]),
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/transmasculine
|
||||
Self::Transmasculine => ColorProfile::from_hex_colors(vec![
|
||||
"#FF8ABD", "#CDF5FE", "#9AEBFF", "#74DFFF", "#9AEBFF", "#CDF5FE", "#FF8ABD",
|
||||
]),
|
||||
|
||||
// used colorpicker to source from https://www.deviantart.com/pride-flags/art/Trans-Woman-Transfeminine-1-543925985
|
||||
// linked from https://gender.fandom.com/wiki/Transfeminine
|
||||
Self::Transfeminine => ColorProfile::from_hex_colors(vec![
|
||||
"#73DEFF", "#FFE2EE", "#FFB5D6", "#FF8DC0", "#FFB5D6", "#FFE2EE", "#73DEFF",
|
||||
]),
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/genderfaun
|
||||
Self::Genderfaun => ColorProfile::from_hex_colors(vec![
|
||||
"#FCD689", "#FFF09B", "#FAF9CD", "#FFFFFF", "#8EDED9", "#8CACDE", "#9782EC",
|
||||
]),
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/demifaun
|
||||
Self::Demifaun => ColorProfile::from_hex_colors(vec![
|
||||
"#7F7F7F", "#C6C6C6", "#FCC688", "#FFF19C", "#FFFFFF", "#8DE0D5", "#9682EC",
|
||||
"#C6C6C6", "#7F7F7F",
|
||||
])
|
||||
.and_then(|c| c.with_weights(vec![2, 2, 1, 1, 1, 1, 1, 2, 2])),
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/genderfae
|
||||
Self::Genderfae => ColorProfile::from_hex_colors(vec![
|
||||
"#97C3A5", "#C3DEAE", "#F9FACD", "#FFFFFF", "#FCA2C4", "#DB8AE4", "#A97EDD",
|
||||
]),
|
||||
|
||||
// used colorpicker to source form https://www.deviantart.com/pride-flags/art/Demifae-870194777
|
||||
Self::Demifae => ColorProfile::from_hex_colors(vec![
|
||||
"#7F7F7F", "#C5C5C5", "#97C3A4", "#C4DEAE", "#FFFFFF", "#FCA2C5", "#AB7EDF",
|
||||
"#C5C5C5", "#7F7F7F",
|
||||
])
|
||||
.and_then(|c| c.with_weights(vec![2, 2, 1, 1, 1, 1, 1, 2, 2])),
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/neutrois
|
||||
Self::Neutrois => ColorProfile::from_hex_colors(vec!["#FFFFFF", "#1F9F00", "#000000"]),
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/biromantic-alternate-2
|
||||
Self::Biromantic1 => ColorProfile::from_hex_colors(vec![
|
||||
"#8869A5", "#D8A7D8", "#FFFFFF", "#FDB18D", "#151638",
|
||||
]),
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/autoromantic
|
||||
Self::Autoromantic => ColorProfile::from_hex_colors(
|
||||
// symbol interpreted
|
||||
vec!["#99D9EA", "#3DA542", "#7F7F7F"],
|
||||
)
|
||||
.and_then(|c| c.with_weights(vec![2, 1, 2])),
|
||||
|
||||
// sourced from https://www.flagcolorcodes.com/boyflux-alternate-2
|
||||
Self::Boyflux2 => ColorProfile::from_hex_colors(vec![
|
||||
"#E48AE4", "#9A81B4", "#55BFAB", "#FFFFFF", "#A8A8A8", "#81D5EF", "#69ABE5",
|
||||
"#5276D4",
|
||||
])
|
||||
.and_then(|c| c.with_weights(vec![1, 1, 1, 1, 1, 5, 5, 5])),
|
||||
|
||||
// sourced from https://commons.wikimedia.org/wiki/File:Girlflux_Pride_Flag.jpg
|
||||
Self::Girlflux => ColorProfile::from_hex_colors(vec![
|
||||
"f9e6d7", "f2526c", "bf0311", "e9c587", "bf0311", "f2526c", "f9e6d7",
|
||||
]),
|
||||
|
||||
// sourced from https://www.deviantart.com/pride-flags/art/Genderflux-1-543925589
|
||||
Self::Genderflux => ColorProfile::from_hex_colors(vec![
|
||||
"f47694", "f2a2b9", "cecece", "7ce0f7", "3ecdf9", "fff48d",
|
||||
]),
|
||||
|
||||
// sourced from https://lgbtqia.wiki/wiki/Finsexual
|
||||
Self::Finsexual => ColorProfile::from_hex_colors(vec![
|
||||
"#B18EDF", "#D7B1E2", "#F7CDE9", "#F39FCE", "#EA7BB3",
|
||||
]),
|
||||
|
||||
// sourced from https://web.archive.org/web/20221002181913/https://unlabeledinfo.carrd.co/#flags
|
||||
Self::Unlabeled1 => {
|
||||
ColorProfile::from_hex_colors(vec!["#EAF8E4", "#FDFDFB", "#E1EFF7", "#F4E2C4"])
|
||||
},
|
||||
|
||||
// sourced from https://web.archive.org/web/20221002181913/https://unlabeledinfo.carrd.co/#flags
|
||||
Self::Unlabeled2 => ColorProfile::from_hex_colors(vec![
|
||||
"#250548", "#FFFFFF", "#F7DCDA", "#EC9BEE", "#9541FA", "#7D2557",
|
||||
]),
|
||||
|
||||
Self::Pangender => ColorProfile::from_hex_colors(vec![
|
||||
"#FFF798", "#FEDDCD", "#FFEBFB", "#FFFFFF", "#FFEBFB", "#FEDDCD", "#FFF798",
|
||||
]),
|
||||
|
||||
// high-contrast version of pangender flag
|
||||
Self::PangenderContrast => ColorProfile::from_hex_colors(vec![
|
||||
"#ffe87f", "#fcbaa6", "#fbc9f3", "#FFFFFF", "#fbc9f3", "#fcbaa6", "#ffe87f",
|
||||
]),
|
||||
|
||||
Self::GenderNonconforming1 => ColorProfile::from_hex_colors(vec![
|
||||
"#50284d", "#96467b", "#5c96f7", "#ffe6f7", "#5c96f7", "#96467b", "#50284d",
|
||||
])
|
||||
.and_then(|c| c.with_weights(vec![4, 1, 1, 1, 1, 1, 4])),
|
||||
|
||||
Self::GenderNonconforming2 => ColorProfile::from_hex_colors(vec![
|
||||
"#50284d", "#96467b", "#5c96f7", "#ffe6f7", "#5c96f7", "#96467b", "#50284d",
|
||||
]),
|
||||
|
||||
Self::Femboy => ColorProfile::from_hex_colors(vec![
|
||||
"#d260a5", "#e4afcd", "#fefefe", "#57cef8", "#fefefe", "#e4afcd", "#d260a5",
|
||||
]),
|
||||
|
||||
Self::Tomboy => ColorProfile::from_hex_colors(vec![
|
||||
"#2f3fb9", "#613a03", "#fefefe", "#f1a9b7", "#fefefe", "#613a03", "#2f3fb9",
|
||||
]),
|
||||
|
||||
// sourced from https://lgbtqia.fandom.com/wiki/Gynesexual
|
||||
Self::Gynesexual => {
|
||||
ColorProfile::from_hex_colors(vec!["#F4A9B7", "#903F2B", "#5B953B"])
|
||||
},
|
||||
|
||||
// sourced from https://lgbtqia.fandom.com/wiki/Androsexual
|
||||
Self::Androsexual => {
|
||||
ColorProfile::from_hex_colors(vec!["#01CCFF", "#603524", "#B799DE"])
|
||||
},
|
||||
|
||||
// sourced from: https://gender.fandom.com/wiki/Gendervoid
|
||||
Self::Gendervoid => ColorProfile::from_hex_colors(vec![
|
||||
"#081149", "#4B484B", "#000000", "#4B484B", "#081149",
|
||||
]),
|
||||
|
||||
// sourced from: https://gender.fandom.com/wiki/Gendervoid
|
||||
Self::Voidgirl => ColorProfile::from_hex_colors(vec![
|
||||
"#180827", "#7A5A8B", "#E09BED", "#7A5A8B", "#180827",
|
||||
]),
|
||||
|
||||
// sourced from: https://gender.fandom.com/wiki/Gendervoid
|
||||
Self::Voidboy => ColorProfile::from_hex_colors(vec![
|
||||
"#0B130C", "#547655", "#66B969", "#547655", "#0B130C",
|
||||
]),
|
||||
|
||||
// used https://twitter.com/foxbrained/status/1667621855518236674/photo/1 as source and colorpicked
|
||||
Self::NonhumanUnity => {
|
||||
ColorProfile::from_hex_colors(vec!["#177B49", "#FFFFFF", "#593C90"])
|
||||
},
|
||||
|
||||
// used https://www.tumblr.com/zombpawcoins/745062851267493888/caninekin-canine-therian-flag
|
||||
Self::Caninekin => ColorProfile::from_hex_colors(vec![
|
||||
"#2d2822", "#543d25", "#9c754d", "#e8dac2", "#cfad8c", "#b77b55", "#954e31",
|
||||
]),
|
||||
|
||||
// used https://pluralpedia.org/w/Plurality#/media/File:Plural-Flag-1.jpg as source and colorpicked
|
||||
Self::Plural => ColorProfile::from_hex_colors(vec![
|
||||
"#2D0625", "#543475", "#7675C3", "#89C7B0", "#F3EDBD",
|
||||
]),
|
||||
|
||||
// sampled from https://es.m.wikipedia.org/wiki/Archivo:Fraysexual_flag.jpg
|
||||
Self::Fraysexual => {
|
||||
ColorProfile::from_hex_colors(vec!["#226CB5", "#94E7DD", "#FFFFFF", "#636363"])
|
||||
},
|
||||
|
||||
// sourced from https://commons.wikimedia.org/wiki/File:Bear_Brotherhood_flag.svg
|
||||
Self::Bear => ColorProfile::from_hex_colors(vec![
|
||||
"#623804", "#D56300", "#FEDD63", "#FEE6B8", "#FFFFFF", "#555555",
|
||||
]),
|
||||
|
||||
// colorpicked from https://commons.wikimedia.org/wiki/File:Butch_Flag.png
|
||||
Self::Butch => ColorProfile::from_hex_colors(vec![
|
||||
"#D72800", "#F17623", "#FF9C56", "#FFFDF6", "#FFCE89", "#FEAF02", "#A37000",
|
||||
]),
|
||||
|
||||
// colorpicked from https://commons.wikimedia.org/wiki/File:Leather,_Latex,_and_BDSM_pride_-_Light.svg
|
||||
Self::Leather => ColorProfile::from_hex_colors(vec![
|
||||
"#000000", "#252580", "#000000", "#252580", "#FFFFFF", "#252580", "#000000",
|
||||
"#252580", "#000000",
|
||||
]),
|
||||
|
||||
// colorpicked from https://commons.wikimedia.org/wiki/File:Official_Otter_Pride_Flag_by_Bearbackgear.jpg
|
||||
Self::Otter => ColorProfile::from_hex_colors(vec![
|
||||
"#263881", "#5C9DC9", "#FFFFFF", "#3A291D", "#5C9DC9", "#263881",
|
||||
]),
|
||||
|
||||
// colorpicked from https://commons.wikimedia.org/wiki/File:Twink_Pride_Flag_(proposed).svg
|
||||
Self::Twink => ColorProfile::from_hex_colors(vec!["#FFB2FF", "#FFFFFF", "#FFFF81"]),
|
||||
|
||||
Self::Kenochoric => {
|
||||
ColorProfile::from_hex_colors(vec!["#000000", "#2E1569", "#824DB7", "#C7A1D6"])
|
||||
},
|
||||
|
||||
Self::Veldian => ColorProfile::from_hex_colors(vec![
|
||||
"#D182A8", "#FAF6E0", "#69ACBE", "#5D448F", "#3A113E",
|
||||
]),
|
||||
|
||||
Self::Solian => ColorProfile::from_hex_colors(vec![
|
||||
"#FFF8ED", "#FFE7A8", "#F1B870", "#A56058", "#46281E",
|
||||
]),
|
||||
|
||||
Self::Lunian => ColorProfile::from_hex_colors(vec![
|
||||
"#2F0E62", "#6F41B1", "#889FDF", "#7DDFD5", "#D2F2E2",
|
||||
]),
|
||||
|
||||
// pulled from https://polyamproud.com/flag
|
||||
Self::Polyam => ColorProfile::from_hex_colors(vec![
|
||||
"#FFFFFF", "#FCBF00", "#009FE3", "#E50051", "#340C46",
|
||||
]),
|
||||
|
||||
Self::Sapphic => ColorProfile::from_hex_colors(vec![
|
||||
"#FD8BA8", "#FBF2FF", "#C76BC5", "#FDD768", "#C76BC5", "#FBF2FF", "#FD8BA8",
|
||||
]),
|
||||
|
||||
Self::Androgyne => ColorProfile::from_hex_colors(vec!["#FE007F", "#9832FF", "#00B8E7"]),
|
||||
|
||||
Self::Interprogress => ColorProfile::from_hex_colors(vec![
|
||||
"#FFD800", "#7902AA", "#FFFFFF", "#FFAFC8", "#74D7EE", "#613915", "#000000",
|
||||
"#E50000", "#FF8D00", "#FFEE00", "#028121", "#004CFF", "#770088",
|
||||
]),
|
||||
|
||||
Self::Progress => ColorProfile::from_hex_colors(vec![
|
||||
"#FFFFFF", "#FFAFC8", "#74D7EE", "#613915", "#000000", "#E50000", "#FF8D00",
|
||||
"#FFEE00", "#028121", "#004CFF", "#770088",
|
||||
]),
|
||||
|
||||
Self::Intersex => ColorProfile::from_hex_colors(vec!["#FFD800", "#7902AA", "#FFD800"])
|
||||
.and_then(|c| c.with_weights(vec![2, 1, 2])),
|
||||
|
||||
Self::OldPolyam => ColorProfile::from_hex_colors(vec![
|
||||
"#0000FF", "#FF0000", "#FFFF00", "#FF0000", "#000000",
|
||||
]),
|
||||
|
||||
Self::EqualRights => ColorProfile::from_hex_colors(vec![
|
||||
"#0000FF", "#FFFF00", "#0000FF", "#FFFF00", "#0000FF",
|
||||
])
|
||||
.and_then(|c| c.with_weights(vec![2, 1, 2, 1, 2])),
|
||||
|
||||
Self::Drag => ColorProfile::from_hex_colors(vec![
|
||||
"#CC67FF", "#FFFFFF", "#FFA3E3", "#FFFFFF", "#3366FF",
|
||||
]),
|
||||
|
||||
Self::Pronounfluid => ColorProfile::from_hex_colors(vec![
|
||||
"#FFB3F9", "#FFFFFF", "#D1FDCB", "#C7B0FF", "#000000", "#B8CCFF",
|
||||
]),
|
||||
|
||||
Self::Pronounflux => ColorProfile::from_hex_colors(vec![
|
||||
"#FDB3F8", "#B6CCFA", "#18DDD3", "#64FF89", "#FF7690", "#FFFFFF",
|
||||
]),
|
||||
|
||||
Self::Exipronoun => {
|
||||
ColorProfile::from_hex_colors(vec!["#1C3D34", "#FFFFFF", "#321848", "#000000"])
|
||||
},
|
||||
|
||||
Self::Neopronoun => {
|
||||
ColorProfile::from_hex_colors(vec!["#BCEC64", "#FFFFFF", "#38077A"])
|
||||
},
|
||||
|
||||
Self::Neofluid => ColorProfile::from_hex_colors(vec![
|
||||
"#FFECA0", "#FFFFFF", "#FFECA0", "#38087A", "#BCEC64",
|
||||
]),
|
||||
|
||||
Self::Genderqueer => {
|
||||
ColorProfile::from_hex_colors(vec!["#B57EDC", "#FFFFFF", "#4A8123"])
|
||||
},
|
||||
|
||||
Self::Beiyang => ColorProfile::from_hex_colors(vec![
|
||||
"#DF1B12", "#FFC600", "#01639D", "#FFFFFF", "#000000",
|
||||
]),
|
||||
|
||||
Self::Burger => ColorProfile::from_hex_colors(vec![
|
||||
"#F3A26A", "#498701", "#FD1C13", "#7D3829", "#F3A26A",
|
||||
]),
|
||||
|
||||
Self::ThroatLozenges => ColorProfile::from_hex_colors(vec![
|
||||
"#2759DA", "#03940D", "#F5F100", "#F59B00", "#B71212",
|
||||
]),
|
||||
|
||||
// used https://gilbertbaker.com/rainbow-flag-color-meanings/ as source and colorpicked
|
||||
Self::Baker => ColorProfile::from_hex_colors(vec![
|
||||
"#F23D9E", "#F80A24", "#F78022", "#F9E81F", "#1E972E", "#1B86BC", "#243897",
|
||||
"#6F0A82",
|
||||
]),
|
||||
})
|
||||
.expect("preset color profiles should be valid")
|
||||
}
|
||||
}
|
||||
|
||||
impl ColorProfile {
|
||||
pub fn new(colors: Vec<Srgb<u8>>) -> Self {
|
||||
Self { colors }
|
||||
}
|
||||
|
||||
pub fn from_hex_colors<S>(hex_colors: Vec<S>) -> Result<Self>
|
||||
where
|
||||
S: AsRef<str>,
|
||||
{
|
||||
let colors = hex_colors
|
||||
.into_iter()
|
||||
.map(|s| s.as_ref().parse())
|
||||
.collect::<Result<_, _>>()
|
||||
.context("failed to parse hex colors")?;
|
||||
Ok(Self::new(colors))
|
||||
}
|
||||
|
||||
/// Maps colors based on weights.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `weights` - Weights of each color (`weights[i]` = how many times
|
||||
/// `colors[i]` appears)
|
||||
pub fn with_weights(&self, weights: Vec<u8>) -> Result<Self> {
|
||||
if weights.len() != self.colors.len() {
|
||||
debug!(?weights, ?self.colors, "length mismatch between `weights` and `colors`");
|
||||
return Err(anyhow!(
|
||||
"`weights` should have the same number of elements as `colors`"
|
||||
));
|
||||
}
|
||||
|
||||
let mut weighted_colors = Vec::new();
|
||||
|
||||
for (i, w) in weights.into_iter().enumerate() {
|
||||
weighted_colors.extend(iter::repeat(self.colors[i]).take(usize::from(w)));
|
||||
}
|
||||
|
||||
Ok(Self::new(weighted_colors))
|
||||
}
|
||||
|
||||
/// Creates a new color profile, with the colors spread to the specified
|
||||
/// length.
|
||||
pub fn with_length(&self, length: NonZeroU8) -> Result<Self> {
|
||||
let orig_len = self.colors.len();
|
||||
let orig_len: NonZeroUsize = orig_len.try_into().expect("`colors` should not be empty");
|
||||
let orig_len: NonZeroU8 = orig_len
|
||||
.try_into()
|
||||
.expect("`colors` should not have more than 255 elements");
|
||||
// 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 = usize::from(orig_len.get() / 2);
|
||||
|
||||
// How many copies of each color should be displayed at least?
|
||||
let repeats = length.get().div_euclid(orig_len.get());
|
||||
let mut weights = vec![repeats; NonZeroUsize::from(orig_len).get()];
|
||||
|
||||
// How many extra spaces left?
|
||||
let mut extras = length.get().rem_euclid(orig_len.get());
|
||||
|
||||
// If there is an odd space left, extend the center by one space
|
||||
if extras % 2 == 1 {
|
||||
weights[center_i] = weights[center_i].checked_add(1).unwrap();
|
||||
extras = extras.checked_sub(1).unwrap();
|
||||
}
|
||||
|
||||
// Add weight to border until there's no space left (extras must be even at this
|
||||
// point)
|
||||
let weights_len = weights.len();
|
||||
for border_i in 0..usize::from(extras / 2) {
|
||||
weights[border_i] = weights[border_i].checked_add(1).unwrap();
|
||||
let border_opp = weights_len
|
||||
.checked_sub(border_i)
|
||||
.unwrap()
|
||||
.checked_sub(1)
|
||||
.unwrap();
|
||||
weights[border_opp] = weights[border_opp].checked_add(1).unwrap();
|
||||
}
|
||||
|
||||
self.with_weights(weights)
|
||||
}
|
||||
|
||||
/// Colors a text.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `foreground_background` - Whether the color is shown on the foreground
|
||||
/// text or the background block
|
||||
/// * `space_only` - Whether to only color spaces
|
||||
pub fn color_text<S>(
|
||||
&self,
|
||||
txt: S,
|
||||
color_mode: AnsiMode,
|
||||
foreground_background: ForegroundBackground,
|
||||
space_only: bool,
|
||||
) -> Result<String>
|
||||
where
|
||||
S: AsRef<str>,
|
||||
{
|
||||
let txt = txt.as_ref();
|
||||
|
||||
let txt: Vec<&str> = txt.graphemes(true).collect();
|
||||
|
||||
let ColorProfile { colors } = {
|
||||
let length = txt.len();
|
||||
let length: NonZeroUsize = length.try_into().context("`txt` should not be empty")?;
|
||||
let length: NonZeroU8 = length.try_into().with_context(|| {
|
||||
format!(
|
||||
"`txt` should not have more than {limit} characters",
|
||||
limit = u8::MAX
|
||||
)
|
||||
})?;
|
||||
self.with_length(length)
|
||||
.with_context(|| format!("failed to spread color profile to length {length}"))?
|
||||
};
|
||||
|
||||
let mut buf = String::new();
|
||||
for (i, &gr) in txt.iter().enumerate() {
|
||||
if space_only && gr != " " {
|
||||
if i > 0 && txt[i.checked_sub(1).unwrap()] == " " {
|
||||
buf.push_str("\x1b[39;49m");
|
||||
}
|
||||
buf.push_str(gr);
|
||||
} else {
|
||||
buf.push_str(&colors[i].to_ansi_string(color_mode, foreground_background));
|
||||
buf.push_str(gr);
|
||||
}
|
||||
}
|
||||
|
||||
buf.push_str("\x1b[39;49m");
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
/// Creates a new color profile, with the colors lightened by a multiplier.
|
||||
pub fn lighten(&self, multiplier: f32) -> Self {
|
||||
let mut rgb_f32_colors: Vec<LinSrgb> =
|
||||
self.colors.iter().map(|c| c.into_linear()).collect();
|
||||
|
||||
{
|
||||
let okhsl_f32_colors: &mut [Okhsl] = &mut rgb_f32_colors.into_color_mut();
|
||||
|
||||
for okhsl_f32_color in okhsl_f32_colors {
|
||||
okhsl_f32_color.lightness *= multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
let rgb_u8_colors: Vec<_> = rgb_f32_colors
|
||||
.into_iter()
|
||||
.map(Srgb::<u8>::from_linear)
|
||||
.collect();
|
||||
|
||||
Self {
|
||||
colors: rgb_u8_colors,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new color profile, with the colors set to the specified
|
||||
/// [`Okhsl`] lightness value.
|
||||
pub fn with_lightness(&self, assign_lightness: AssignLightness) -> Self {
|
||||
let mut rgb_f32_colors: Vec<LinSrgb> =
|
||||
self.colors.iter().map(|c| c.into_linear()).collect();
|
||||
|
||||
{
|
||||
let okhsl_f32_colors: &mut [Okhsl] = &mut rgb_f32_colors.into_color_mut();
|
||||
|
||||
for okhsl_f32_color in okhsl_f32_colors {
|
||||
match assign_lightness {
|
||||
AssignLightness::Replace(lightness) => {
|
||||
okhsl_f32_color.lightness = lightness.into();
|
||||
},
|
||||
AssignLightness::ClampMax(lightness) => {
|
||||
okhsl_f32_color.lightness.clamp_max_assign(lightness.into());
|
||||
},
|
||||
AssignLightness::ClampMin(lightness) => {
|
||||
okhsl_f32_color.lightness.clamp_min_assign(lightness.into());
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let rgb_u8_colors: Vec<Srgb<u8>> = rgb_f32_colors
|
||||
.into_iter()
|
||||
.map(Srgb::<u8>::from_linear)
|
||||
.collect();
|
||||
|
||||
Self {
|
||||
colors: rgb_u8_colors,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new color profile, with the colors set to the specified
|
||||
/// [`Okhsl`] lightness value, adapted to the terminal theme.
|
||||
pub fn with_lightness_adaptive(&self, lightness: Lightness, theme: TerminalTheme) -> Self {
|
||||
match theme {
|
||||
TerminalTheme::Dark => self.with_lightness(AssignLightness::ClampMin(lightness)),
|
||||
TerminalTheme::Light => self.with_lightness(AssignLightness::ClampMax(lightness)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates another color profile with only the unique colors.
|
||||
pub fn unique_colors(&self) -> Self {
|
||||
let unique_colors: IndexSet<[u8; 3]> = self.colors.iter().map(|&c| c.into()).collect();
|
||||
let unique_colors: Vec<Srgb<u8>> = unique_colors.into_iter().map(|c| c.into()).collect();
|
||||
Self::new(unique_colors)
|
||||
}
|
||||
}
|
||||
include!(concat!(env!("OUT_DIR"), "/presets.rs"));
|
||||
|
||||
@@ -47,58 +47,32 @@ pub fn start_animation(color_mode: AnsiMode) -> Result<()> {
|
||||
};
|
||||
|
||||
let text = &TEXT_ASCII[1..TEXT_ASCII.len().checked_sub(1).unwrap()];
|
||||
let (text_width, text_height) =
|
||||
ascii_size(text).expect("text ascii should have valid width and height");
|
||||
let (text_w, text_h) = ascii_size(text)?;
|
||||
let (text, text_width, text_height) = {
|
||||
const TEXT_BORDER_WIDTH: u16 = 2;
|
||||
const NOTICE_BORDER_WIDTH: u16 = 1;
|
||||
const VERTICAL_MARGIN: u16 = 1;
|
||||
let notice_w = NOTICE.len();
|
||||
let notice_w: u8 = notice_w
|
||||
.try_into()
|
||||
.expect("`NOTICE` width should fit in `u8`");
|
||||
let notice_h = NOTICE.lines().count();
|
||||
let notice_h: u8 = notice_h
|
||||
.try_into()
|
||||
.expect("`NOTICE` height should fit in `u8`");
|
||||
let notice_w: u16 = NOTICE.len().try_into()?;
|
||||
let notice_h: u16 = NOTICE.lines().count().try_into()?;
|
||||
let term_w_min = cmp::max(
|
||||
u16::from(text_width)
|
||||
.checked_add(TEXT_BORDER_WIDTH.checked_mul(2).unwrap())
|
||||
.unwrap(),
|
||||
u16::from(notice_w)
|
||||
.checked_add(NOTICE_BORDER_WIDTH.checked_mul(2).unwrap())
|
||||
.unwrap(),
|
||||
text_w + TEXT_BORDER_WIDTH * 2,
|
||||
notice_w + NOTICE_BORDER_WIDTH * 2,
|
||||
);
|
||||
let term_h_min = u16::from(text_height)
|
||||
.checked_add(notice_h.into())
|
||||
.unwrap()
|
||||
.checked_add(VERTICAL_MARGIN.checked_mul(2).unwrap())
|
||||
.unwrap();
|
||||
let term_h_min = u16::from(text_h) + notice_h + VERTICAL_MARGIN * 2;
|
||||
if w.get() >= term_w_min && h.get() >= term_h_min {
|
||||
(text, text_width, text_height)
|
||||
(text, text_w, text_h)
|
||||
} else {
|
||||
let text = &TEXT_ASCII_SMALL[1..TEXT_ASCII_SMALL.len().checked_sub(1).unwrap()];
|
||||
let (text_width, text_height) =
|
||||
ascii_size(text).expect("text ascii should have valid width and height");
|
||||
let (text_w, text_h) = ascii_size(text)?;
|
||||
let term_w_min = cmp::max(
|
||||
u16::from(text_width)
|
||||
.checked_add(TEXT_BORDER_WIDTH.checked_mul(2).unwrap())
|
||||
.unwrap(),
|
||||
u16::from(notice_w)
|
||||
.checked_add(NOTICE_BORDER_WIDTH.checked_mul(2).unwrap())
|
||||
.unwrap(),
|
||||
text_w + TEXT_BORDER_WIDTH * 2,
|
||||
notice_w + NOTICE_BORDER_WIDTH * 2,
|
||||
);
|
||||
let term_h_min = u16::from(text_height)
|
||||
.checked_add(notice_h.into())
|
||||
.unwrap()
|
||||
.checked_add(VERTICAL_MARGIN.checked_mul(2).unwrap())
|
||||
.unwrap();
|
||||
let term_h_min = text_h + notice_h + VERTICAL_MARGIN * 2;
|
||||
if w.get() < term_w_min || h.get() < term_h_min {
|
||||
return Err(anyhow!(
|
||||
"terminal size should be at least ({term_w_min} * {term_h_min})"
|
||||
));
|
||||
return Err(anyhow!("terminal size should be at least ({term_w_min} * {term_h_min})"));
|
||||
}
|
||||
(text, text_width, text_height)
|
||||
(text, text_w, text_h)
|
||||
}
|
||||
};
|
||||
let text_lines: Vec<&str> = text.lines().collect();
|
||||
@@ -165,8 +139,7 @@ pub fn start_animation(color_mode: AnsiMode) -> Result<()> {
|
||||
.rem_euclid(colors.len())]
|
||||
.to_ansi_string(color_mode, ForegroundBackground::Background),
|
||||
fg = fg.to_ansi_string(color_mode, ForegroundBackground::Foreground)
|
||||
)
|
||||
.unwrap();
|
||||
)?;
|
||||
|
||||
// Loop over the width
|
||||
for x in 0..w.get() {
|
||||
@@ -176,27 +149,11 @@ pub fn start_animation(color_mode: AnsiMode) -> Result<()> {
|
||||
.wrapping_add_signed((2.0 * (y as f64 + 0.5 * frame as f64).sin()) as isize);
|
||||
let y_text = text_start_y <= y && y < text_end_y;
|
||||
|
||||
let border = 1u16
|
||||
.checked_add(
|
||||
if y == text_start_y || y == text_end_y.checked_sub(1).unwrap() {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
let text_bounds_x1 = text_start_x
|
||||
.checked_sub(border)
|
||||
.expect("`text_start_x - border` should not underflow `u16`");
|
||||
let text_bounds_x2 = text_end_x
|
||||
.checked_add(border)
|
||||
.expect("`text_end_x + border` should not overflow `u16`");
|
||||
let notice_bounds_x1 = notice_start_x
|
||||
.checked_sub(1)
|
||||
.expect("`notice_start_x - 1` should not underflow `u16`");
|
||||
let notice_bounds_x2 = notice_end_x
|
||||
.checked_add(1)
|
||||
.expect("`notice_end_x + 1` should not overflow `u16`");
|
||||
let border = 1u16 + if y == text_start_y || y == (text_end_y - 1) { 0 } else { 1 };
|
||||
let text_bounds_x1 = text_start_x - border;
|
||||
let text_bounds_x2 = text_end_x - border;
|
||||
let notice_bounds_x1 = notice_start_x - 1;
|
||||
let notice_bounds_x2 = notice_end_x - 1;
|
||||
|
||||
// If it's a switching point
|
||||
if idx.rem_euclid(NonZeroUsize::from(block_width).get()) == 0
|
||||
@@ -215,19 +172,9 @@ pub fn start_animation(color_mode: AnsiMode) -> Result<()> {
|
||||
{
|
||||
let c: LinSrgba = c.with_alpha(1.0).into_linear();
|
||||
let c = Srgb::<u8>::from_linear(c.overlay(black).without_alpha());
|
||||
write!(
|
||||
buf,
|
||||
"{bg}",
|
||||
bg = c.to_ansi_string(color_mode, ForegroundBackground::Background),
|
||||
)
|
||||
.unwrap();
|
||||
write!(buf, "{bg}", bg = c.to_ansi_string(color_mode, ForegroundBackground::Background))?;
|
||||
} else {
|
||||
write!(
|
||||
buf,
|
||||
"{bg}",
|
||||
bg = c.to_ansi_string(color_mode, ForegroundBackground::Background),
|
||||
)
|
||||
.unwrap();
|
||||
write!(buf, "{bg}", bg = c.to_ansi_string(color_mode, ForegroundBackground::Background))?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,8 +187,7 @@ pub fn start_animation(color_mode: AnsiMode) -> Result<()> {
|
||||
.chars()
|
||||
.nth(usize::from(x.checked_sub(text_start_x).unwrap()))
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
)?;
|
||||
} else if y == notice_y && notice_start_x <= x && x < notice_end_x {
|
||||
write!(
|
||||
buf,
|
||||
@@ -250,21 +196,15 @@ pub fn start_animation(color_mode: AnsiMode) -> Result<()> {
|
||||
.chars()
|
||||
.nth(usize::from(x.checked_sub(notice_start_x).unwrap()))
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
)?;
|
||||
} else {
|
||||
write!(buf, " ").unwrap();
|
||||
write!(buf, " ")?;
|
||||
}
|
||||
}
|
||||
|
||||
// New line if it isn't the last line
|
||||
if y != h.get().checked_sub(1).unwrap() {
|
||||
writeln!(
|
||||
buf,
|
||||
"{reset}",
|
||||
reset = color("&r", color_mode).expect("reset should be valid"),
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(buf, "{reset}", reset = color("&r", color_mode)?)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,11 +247,13 @@ pub fn start_animation(color_mode: AnsiMode) -> Result<()> {
|
||||
let mut frame: Wrapping<usize> = Wrapping(0);
|
||||
|
||||
const SPEED: u8 = 2;
|
||||
let frame_delay = Duration::from_secs_f32(1.0 / 25.0);
|
||||
let frame_delay = Duration::from_secs_f32(2.0 / 25.0);
|
||||
|
||||
execute!(io::stdout(), EnterAlternateScreen).context("failed to enter alternate screen")?;
|
||||
|
||||
loop {
|
||||
// Move cursor to the top left corner
|
||||
print!("\x1B[H");
|
||||
draw_frame(frame.0)?;
|
||||
frame += usize::from(SPEED);
|
||||
thread::sleep(frame_delay);
|
||||
|
||||
@@ -36,6 +36,12 @@ pub enum TerminalTheme {
|
||||
Dark,
|
||||
}
|
||||
|
||||
impl Default for TerminalTheme {
|
||||
fn default() -> Self {
|
||||
Self::Dark
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Copy,
|
||||
Clone,
|
||||
|
||||
@@ -16,6 +16,12 @@ pub fn get_cache_path() -> Result<PathBuf> {
|
||||
.context("failed to get base dirs")?
|
||||
.cache_dir()
|
||||
.to_owned();
|
||||
|
||||
// Make sure the cache directory exists
|
||||
if !path.exists() {
|
||||
fs::create_dir_all(&path).with_context(|| format!("failed to create cache dir {path:?}"))?;
|
||||
}
|
||||
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
|
||||
+40
-38
@@ -1,78 +1,80 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH VERSION "1" "October 2024" "Version is 1.99.0" "User Commands"
|
||||
.TH VERSION: "1" "October 2025" "Version: 2.0.3" "User Commands"
|
||||
.SH NAME
|
||||
Version \- manual page for Version is 1.99.0
|
||||
Version: \- manual page for Version: 2.0.3
|
||||
.SH SYNOPSIS
|
||||
.B hyfetch
|
||||
[\fI\,-c\/\fR] [\fI\,-C=CONFIG_FILE\/\fR] [\fI\,-p=PRESET\/\fR] [\fI\,-m=MODE\/\fR] [\fI\,-b=BACKEND\/\fR] [\fI\,--args=ARGS\/\fR] [\fI\,--c-scale=\/\fR
|
||||
.SH DESCRIPTION
|
||||
usage: hyfetch [\-h] [\-c] [\-C CONFIG_FILE]
|
||||
.IP
|
||||
[\-p {rainbow,transgender,nonbinary,xenogender,agender,queer,genderfluid,bisexual,pansexual,polysexual,omnisexual,omniromantic,gay\-men,lesbian,abrosexual,asexual,aromantic,aroace1,aroace2,aroace3,autosexual,intergender,greygender,akiosexual,bigender,demigender,demiboy,demigirl,transmasculine,transfeminine,genderfaun,demifaun,genderfae,demifae,neutrois,biromantic1,biromantic2,autoromantic,boyflux2,girlflux,genderflux,finsexual,unlabeled1,unlabeled2,pangender,pangender.contrast,gendernonconforming1,gendernonconforming2,femboy,tomboy,gynesexual,androsexual,gendervoid,voidgirl,voidboy,nonhuman\-unity,plural,fraysexual,bear,butch,leather,otter,twink,kenochoric,veldian,solian,lunian,polyam,sapphic,androgyne,interprogress,progress,intersex,old\-polyam,equal\-rights,drag,pronounfluid,pronounflux,exipronoun,neopronoun,neofluid,genderqueer,beiyang,burger,baker,caninekin,random}]
|
||||
[\-m {8bit,rgb}]
|
||||
[\-b {qwqfetch,neofetch,fastfetch,fastfetch\-old}] [\-\-args ARGS]
|
||||
[\-\-c\-scale SCALE] [\-\-c\-set\-l LIGHT] [\-\-c\-overlay] [\-V] [\-\-june]
|
||||
[\-\-debug] [\-\-distro DISTRO] [\-\-ascii\-file ASCII_FILE]
|
||||
[\-\-print\-font\-logo]
|
||||
SCALE] [\-\-c\-set\-l=LIGHTNESS] [\-\-june] [\-\-debug] ([\-\-distro=DISTRO] | [\-\-test\-distro=DISTRO]) [
|
||||
\fB\-\-ascii\-file\fR=\fI\,ASCII_FILE]\/\fR [\-\-print\-font\-logo] [\-\-auto\-detect\-light\-dark=BOOL]
|
||||
.PP
|
||||
[1m[38;5;14mhyfetch[39m[22m \- neofetch with flags <3
|
||||
.SS "options:"
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
show this help message and exit
|
||||
.SS "Available options:"
|
||||
.TP
|
||||
\fB\-c\fR, \fB\-\-config\fR
|
||||
Configure hyfetch
|
||||
.TP
|
||||
\fB\-C\fR CONFIG_FILE, \fB\-\-config\-file\fR CONFIG_FILE
|
||||
\fB\-C\fR, \fB\-\-config\-file\fR=\fI\,CONFIG_FILE\/\fR
|
||||
Use another config file
|
||||
[default: "/home/azalea/.config/hyfetch.json"]
|
||||
.TP
|
||||
\fB\-p\fR {rainbow,transgender,nonbinary,xenogender,agender,queer,genderfluid,bisexual,pansexual,polysexual,omnisexual,omniromantic,gay\-men,lesbian,abrosexual,asexual,aromantic,aroace1,aroace2,aroace3,autosexual,intergender,greygender,akiosexual,bigender,demigender,demiboy,demigirl,transmasculine,transfeminine,genderfaun,demifaun,genderfae,demifae,neutrois,biromantic1,biromantic2,autoromantic,boyflux2,girlflux,genderflux,finsexual,unlabeled1,unlabeled2,pangender,pangender.contrast,gendernonconforming1,gendernonconforming2,femboy,tomboy,gynesexual,androsexual,gendervoid,voidgirl,voidboy,nonhuman\-unity,plural,fraysexual,bear,butch,leather,otter,twink,kenochoric,veldian,solian,lunian,polyam,sapphic,androgyne,interprogress,progress,intersex,old\-polyam,equal\-rights,drag,pronounfluid,pronounflux,exipronoun,neopronoun,neofluid,genderqueer,beiyang,burger,baker,caninekin,random}, \fB\-\-preset\fR {rainbow,transgender,nonbinary,xenogender,agender,queer,genderfluid,bisexual,pansexual,polysexual,omnisexual,omniromantic,gay\-men,lesbian,abrosexual,asexual,aromantic,aroace1,aroace2,aroace3,autosexual,intergender,greygender,akiosexual,bigender,demigender,demiboy,demigirl,transmasculine,transfeminine,genderfaun,demifaun,genderfae,demifae,neutrois,biromantic1,biromantic2,autoromantic,boyflux2,girlflux,genderflux,finsexual,unlabeled1,unlabeled2,pangender,pangender.contrast,gendernonconforming1,gendernonconforming2,femboy,tomboy,gynesexual,androsexual,gendervoid,voidgirl,voidboy,nonhuman\-unity,plural,fraysexual,bear,butch,leather,otter,twink,kenochoric,veldian,solian,lunian,polyam,sapphic,androgyne,interprogress,progress,intersex,old\-polyam,equal\-rights,drag,pronounfluid,pronounflux,exipronoun,neopronoun,neofluid,genderqueer,beiyang,burger,baker,caninekin,random}
|
||||
Use preset
|
||||
\fB\-p\fR, \fB\-\-preset\fR=\fI\,PRESET\/\fR
|
||||
Use preset or comma\-separated color list or comma\-separated hex colors
|
||||
(e.g., "#ff0000,#00ff00,#0000ff")
|
||||
PRESET={rainbow,transgender,nonbinary,xenogender,agender,queer,genderfluid,bisexual,pansexual,polysexual,omnisexual,omniromantic,gay\-men,lesbian,abrosexual,asexual,aromantic,fictosexual,aroace1,aroace2,aroace3,autosexual,intergender,greygender,akiosexual,bigender,demigender,demiboy,demigirl,transmasculine,transfeminine,genderfaun,demifaun,genderfae,demifae,neutrois,biromantic1,biromantic2,autoromantic,boyflux2,girlflux,genderflux,nullflux,hypergender,hyperboy,hypergirl,hyperandrogyne,hyperneutrois,finsexual,unlabeled1,unlabeled2,pangender,pangender.contrast,gendernonconforming1,gendernonconforming2,femboy,tomboy,gynesexual,androsexual,gendervoid,voidgirl,voidboy,nonhuman\-unity,plural,fraysexual,bear,butch,leather,otter,twink,adipophilia,kenochoric,veldian,solian,lunian,polyam,sapphic,androgyne,interprogress,progress,intersex,old\-polyam,equal\-rights,drag,pronounfluid,pronounflux,exipronoun,neopronoun,neofluid,genderqueer,cisgender,baker,caninekin,libragender,librafeminine,libramasculine,libraandrogyne,libranonbinary,fluidflux1,fluidflux2,beiyang,burger,throatlozenges,band,random}
|
||||
.TP
|
||||
\fB\-m\fR {8bit,rgb}, \fB\-\-mode\fR {8bit,rgb}
|
||||
Color mode
|
||||
\fB\-m\fR, \fB\-\-mode\fR=\fI\,MODE\/\fR
|
||||
Color mode MODE={8bit,rgb}
|
||||
.TP
|
||||
\fB\-b\fR {qwqfetch,neofetch,fastfetch,fastfetch\-old}, \fB\-\-backend\fR {qwqfetch,neofetch,fastfetch,fastfetch\-old}
|
||||
Choose a *fetch backend
|
||||
\fB\-b\fR, \fB\-\-backend\fR=\fI\,BACKEND\/\fR
|
||||
Choose a *fetch backend BACKEND={neofetch,fastfetch,macchina}
|
||||
.TP
|
||||
\fB\-\-args\fR ARGS
|
||||
\fB\-\-args\fR=\fI\,ARGS\/\fR
|
||||
Additional arguments pass\-through to backend
|
||||
.TP
|
||||
\fB\-\-c\-scale\fR SCALE
|
||||
\fB\-\-c\-scale\fR=\fI\,SCALE\/\fR
|
||||
Lighten colors by a multiplier
|
||||
.TP
|
||||
\fB\-\-c\-set\-l\fR LIGHT
|
||||
\fB\-\-c\-set\-l\fR=\fI\,LIGHTNESS\/\fR
|
||||
Set lightness value of the colors
|
||||
.TP
|
||||
\fB\-\-c\-overlay\fR
|
||||
Use experimental overlay color adjusting instead of
|
||||
HSL lightness
|
||||
.TP
|
||||
\fB\-V\fR, \fB\-\-version\fR
|
||||
Check version
|
||||
.TP
|
||||
\fB\-\-june\fR
|
||||
Show pride month easter egg
|
||||
.TP
|
||||
\fB\-\-debug\fR
|
||||
Debug mode
|
||||
.TP
|
||||
\fB\-\-distro\fR DISTRO, \fB\-\-test\-distro\fR DISTRO
|
||||
\fB\-\-distro\fR=\fI\,DISTRO\/\fR
|
||||
Test for a specific distro
|
||||
.TP
|
||||
\fB\-\-ascii\-file\fR ASCII_FILE
|
||||
\fB\-\-test\-distro\fR=\fI\,DISTRO\/\fR
|
||||
Test for a specific distro
|
||||
.TP
|
||||
\fB\-\-ascii\-file\fR=\fI\,ASCII_FILE\/\fR
|
||||
Use a specific file for the ascii art
|
||||
.TP
|
||||
\fB\-\-print\-font\-logo\fR
|
||||
Print the Font Logo / Nerd Font icon of your distro
|
||||
and exit
|
||||
Print the Font Logo / Nerd Font icon of your distro and exit
|
||||
.TP
|
||||
\fB\-\-auto\-detect\-light\-dark\fR=\fI\,BOOL\/\fR
|
||||
Enables hyfetch to detect light/dark terminal background in
|
||||
runtime
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
Prints help information
|
||||
.TP
|
||||
\fB\-V\fR, \fB\-\-version\fR
|
||||
Prints version information
|
||||
.SH "SEE ALSO"
|
||||
The full documentation for
|
||||
.B Version
|
||||
.B Version:
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B Version
|
||||
.B Version:
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info Version
|
||||
.B info Version:
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
|
||||
+38
-39
@@ -1,7 +1,7 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH NEOFETCH "1" "October 2024" "Neofetch 7.98.0" "User Commands"
|
||||
.TH NEOFETCH "1" "October 2025" "Neofetch 8.0.3" "User Commands"
|
||||
.SH NAME
|
||||
Neofetch \- manual page for Neofetch 7.98.0
|
||||
Neofetch \- manual page for Neofetch 8.0.3
|
||||
.SH SYNOPSIS
|
||||
.B neofetch
|
||||
\fI\,func_name --option "value" --option "value"\/\fR
|
||||
@@ -321,12 +321,12 @@ Amazon, AmogOS, Anarchy, Android, Antergos, antiX, AOSC OS, Aperio
|
||||
GNU/Linux, Aperture, Apricity, Arch, ArchBox, Archcraft,
|
||||
archcraft_ascii, archcraft_minimal, ARCHlabs, ArchMerge, ArchStrike,
|
||||
ArcoLinux, Arkane, ArseLinux, Artix, Arya, Asahi, AsteroidOS, astOS,
|
||||
Astra Linux, Athena, azos, Bedrock, BigLinux, BigLinux_large,
|
||||
Bitrig, BlackArch, BlackMesa, blackPanther, BLAG, BlankOn,
|
||||
BlueLight, Bodhi, bonsai, BSD, BunsenLabs, CachyOS, Calculate,
|
||||
CalinixOS, Carbs, CBL\-Mariner, CelOS, Center, CentOS, Chakra,
|
||||
ChaletOS, Chapeau, Chimera, ChonkySealOS, Chrom, Cleanjaro, Clear
|
||||
Linux OS, ClearOS, Clover, Cobalt, Condres, Container Linux by
|
||||
Astra Linux, Athena, azos, Bazzite, Bedrock, BigLinux,
|
||||
BigLinux_large, Bitrig, BlackArch, BlackMesa, blackPanther, BLAG,
|
||||
BlankOn, BlueLight, Bodhi, bonsai, BSD, BunsenLabs, CachyOS,
|
||||
Calculate, CalinixOS, Carbs, CBL\-Mariner, CelOS, Center, CentOS,
|
||||
Chakra, ChaletOS, Chapeau, Chimera, ChonkySealOS, Chrom, Cleanjaro,
|
||||
Clear Linux OS, ClearOS, Clover, Cobalt, Condres, Container Linux by
|
||||
CoreOS, CRUX, Crystal Linux, Cucumber, CutefishOS, CuteOS, CyberOS,
|
||||
dahlia, DarkOs, Darwin, Debian, Deepin, DesaOS, Devuan, DietPi,
|
||||
digital UNIX, DracOS, DragonFly, Drauger, Droidian, Elementary,
|
||||
@@ -335,37 +335,36 @@ EvolutionOS, eweOS, Exherbo, Exodia Predator OS, Fedora, Fedora
|
||||
Kinoite, Fedora Sericea, Fedora Silverblue, Fedora_unicode,
|
||||
FemboyOS, Feren, Finnix, Floflis, FreeBSD, FreeMiNT, Frugalware,
|
||||
Funtoo, Furreto, GalliumOS, Garuda, Gentoo, GhostBSD, glaucus,
|
||||
gNewSense, GNOME, GNU, GoboLinux, GrapheneOS, Grombyang, Guix,
|
||||
Haiku, HamoniKR, HarDClanZ, Hash, Huayra, Hybrid, HydroOS,
|
||||
Hyperbola, iglunix, instantOS, Interix, IRIX, Ironclad, Itc,
|
||||
januslinux, Kaisen, Kali, KaOS, KDE, Kibojoe, Kogaion, Korora,
|
||||
KrassOS, KSLinux, Kubuntu, LainOS, LangitKetujuh, LaxerOS, LEDE,
|
||||
LibreELEC, Linspire, Linux, Linux Lite, Linux Mint, Linux Mint Old,
|
||||
LinuxFromScratch, Live Raizo, LMDE, Lubuntu, Lunar, mac, MacaroniOS,
|
||||
Mageia, Magix, MagpieOS, MainsailOS, Mandriva, Manjaro, MassOS,
|
||||
MatuusOS, Maui, Mauna, Meowix, Mer, Minix, MIRACLE LINUX, MX, Namib,
|
||||
NekOS, Neptune, NetBSD, Netrunner, Nitrux, NixOS, nixos_colorful,
|
||||
Nobara, NomadBSD, Nurunner, NuTyX, Obarun, OBRevenge, OmniOS, Open
|
||||
Source Media Center, OpenBSD, openEuler, OpenIndiana, openKylin,
|
||||
openmamba, OpenMandriva, OpenStage, openSUSE, openSUSE Leap,
|
||||
openSUSE Tumbleweed, OPNsense, Oracle, orchid, OS Elbrus, PacBSD,
|
||||
Panwah, Parabola, parch, Pardus, Parrot, Parsix, PCBSD, PCLinuxOS,
|
||||
pearOS, Pengwin, Pentoo, Peppermint, Peropesis, phyOS, PikaOS, Pisi,
|
||||
PNM Linux, Pop!_OS, Porteus, PostMarketOS, Profelis SambaBOX,
|
||||
Proxmox, PuffOS, Puppy, PureOS, Q4OS, Qubes, Qubyt, Quibian, Radix,
|
||||
Raspbian, ravynOS, Reborn OS, Red Star, Redcore, Redhat, Refracted
|
||||
Devuan, Regata, Regolith, RhaymOS, rocky, Rosa, Sabayon, sabotage,
|
||||
Sailfish, SalentOS, Salient OS, Salix, Sasanqua, Scientific, semc,
|
||||
Septor, Serene, SharkLinux, ShastraOS, Siduction, SkiffOS, Slackel,
|
||||
Slackware, SliTaz, SmartOS, Soda, Solus, Source Mage, Sparky, Star,
|
||||
SteamOS, Stock Linux, Sulin, SunOS, SwagArch, t2, Tails, Tatra,
|
||||
TeArch, TorizonCore, Trisquel, Twister, Ubuntu, Ubuntu Budgie,
|
||||
Ubuntu Cinnamon, Ubuntu Kylin, Ubuntu MATE, Ubuntu Studio, Ubuntu
|
||||
Sway, Ubuntu Touch, Ubuntu\-GNOME, ubuntu_old02, Ultramarine Linux,
|
||||
unicodearch, Univalent, Univention, Uos, UrukOS, uwuntu, Vanilla,
|
||||
Venom, VNux, Void, VzLinux, wii\-linux\-ngx, Windows, Windows 10,
|
||||
Windows 11, Windows95, Wrt, Xenia, Xenia2, XFerience, Xray_OS,
|
||||
Xubuntu, yiffOS, Zorin have ascii logos.
|
||||
Gloire, gNewSense, GNOME, GNU, GoboLinux, GrapheneOS, Grombyang,
|
||||
Guix, Haiku, HamoniKR, HarDClanZ, Hash, Huayra, Hybrid, HydroOS,
|
||||
Hyperbola, iglunix, instantOS, Interix, IRIX, Itc, januslinux,
|
||||
Kaisen, Kali, KaOS, KDE, Kibojoe, Kogaion, Korora, KrassOS, KSLinux,
|
||||
Kubuntu, LainOS, LangitKetujuh, LaxerOS, LEDE, LibreELEC, Linspire,
|
||||
Linux, Linux Lite, Linux Mint, Linux Mint Old, LinuxFromScratch,
|
||||
Live Raizo, LMDE, Lubuntu, Lunar, mac, MacaroniOS, Mageia, Magix,
|
||||
MagpieOS, MainsailOS, Mandriva, Manjaro, MassOS, MatuusOS, Maui,
|
||||
Mauna, Meowix, Mer, Minix, MIRACLE LINUX, MX, Namib, NekOS, Neptune,
|
||||
NetBSD, Netrunner, Nitrux, NixOS, nixos_colorful, Nobara, NomadBSD,
|
||||
Nurunner, NuTyX, Obarun, OBRevenge, OmniOS, Open Source Media
|
||||
Center, OpenBSD, openEuler, OpenIndiana, openKylin, openmamba,
|
||||
OpenMandriva, OpenStage, openSUSE, openSUSE Leap, openSUSE
|
||||
Tumbleweed, openSUSE Tumbleweed\-Slowroll, OPNsense, Oracle, orchid,
|
||||
OS Elbrus, PacBSD, Panwah, Parabola, parch, Pardus, Parrot, Parsix,
|
||||
PCBSD, PCLinuxOS, pearOS, Pengwin, Pentoo, Peppermint, Peropesis,
|
||||
phyOS, PikaOS, Pisi, PNM Linux, Pop!_OS, Porteus, PostMarketOS,
|
||||
Profelis SambaBOX, Proxmox, PuffOS, Puppy, PureOS, Q4OS, Qubes,
|
||||
Qubyt, Quibian, Radix, Raspbian, ravynOS, Reborn OS, Red Star,
|
||||
Redcore, Redhat, Refracted Devuan, Regata, Regolith, RhaymOS, Rhino
|
||||
Linux, rocky, Rosa, Sabayon, sabotage, Sailfish, SalentOS, Salient
|
||||
OS, Salix, Sasanqua, Scientific, semc, Septor, Serene, SharkLinux,
|
||||
ShastraOS, Siduction, SkiffOS, Slackel, Slackware, SliTaz, SmartOS,
|
||||
Soda, Solus, Source Mage, Sparky, Star, SteamOS, Stock Linux, Sulin,
|
||||
SunOS, SwagArch, t2, Tails, Tatra, TeArch, TorizonCore, Trisquel,
|
||||
Twister, Ubuntu, Ubuntu Budgie, Ubuntu Cinnamon, Ubuntu Kylin,
|
||||
Ubuntu MATE, Ubuntu Studio, Ubuntu Sway, Ubuntu Touch, Ubuntu\-GNOME,
|
||||
ubuntu_old02, Ultramarine Linux, unicodearch, Univalent, Univention,
|
||||
Uos, UrukOS, uwuntu, Vanilla, Venom, VNux, Void, VzLinux, wii\-linuxngx, Windows, Windows 10, Windows 11, Windows95, Wrt, Xenia, Xenia2,
|
||||
XFerience, Xray_OS, Xubuntu, yiffOS, Zorin have ascii logos.
|
||||
.TP
|
||||
NOTE: arch, dragonfly, Fedora, LangitKetujuh, nixos, redhat, Ubuntu
|
||||
have 'old' logo variants, use {distro}_old to use them.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
|
||||
from .py import run_py
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
VERSION = '1.99.0'
|
||||
from __future__ import annotations
|
||||
|
||||
VERSION = '2.0.3'
|
||||
|
||||
+11
-3
@@ -135,9 +135,17 @@ class RGB:
|
||||
:return: RGB object
|
||||
"""
|
||||
hex = hex.lstrip("#")
|
||||
r = int(hex[0:2], 16)
|
||||
g = int(hex[2:4], 16)
|
||||
b = int(hex[4:6], 16)
|
||||
|
||||
if len(hex) == 6:
|
||||
r = int(hex[0:2], 16)
|
||||
g = int(hex[2:4], 16)
|
||||
b = int(hex[4:6], 16)
|
||||
elif len(hex) == 3:
|
||||
r = int(hex[0] * 2, 16)
|
||||
g = int(hex[1] * 2, 16)
|
||||
b = int(hex[2] * 2, 16)
|
||||
else:
|
||||
raise ValueError(f"Error: invalid hex length")
|
||||
return cls(r, g, b)
|
||||
|
||||
def to_ansi_rgb(self, foreground: bool = True) -> str:
|
||||
|
||||
@@ -9,6 +9,7 @@ from .types import LightDark
|
||||
from .__version__ import VERSION
|
||||
|
||||
CONFIG_PATH = Path.home() / '.config/hyfetch.json'
|
||||
SRC = Path(__file__).parent
|
||||
|
||||
|
||||
TEST_ASCII = r"""
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
"Alpine": "",
|
||||
"AOSC OS": "",
|
||||
"Apple": "",
|
||||
"macOS": "",
|
||||
"iOS": "",
|
||||
"Archcraft": "",
|
||||
"ArchLabs": "",
|
||||
"Arch": "",
|
||||
@@ -118,4 +120,4 @@
|
||||
"Xorg": "",
|
||||
"Zorin OS": "",
|
||||
"Windows": "\uE62A"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
{
|
||||
"rainbow": ["#E50000", "#FF8D00", "#FFEE00", "#028121", "#004CFF", "#770088"],
|
||||
"transgender": ["#55CDFD", "#F6AAB7", "#FFFFFF", "#F6AAB7", "#55CDFD"],
|
||||
"nonbinary": ["#FCF431", "#FCFCFC", "#9D59D2", "#282828"],
|
||||
"xenogender": {
|
||||
"colors": ["#FF6692", "#FF9A98", "#FFB883", "#FBFFA8", "#85BCFF", "#9D85FF", "#A510FF"],
|
||||
"comment": "xenogender sourced from https://commons.wikimedia.org/wiki/File:Xenogender_pride_flag.svg"
|
||||
},
|
||||
"agender": ["#000000", "#BABABA", "#FFFFFF", "#BAF484", "#FFFFFF", "#BABABA", "#000000"],
|
||||
"queer": ["#B57FDD", "#FFFFFF", "#49821E"],
|
||||
"genderfluid": ["#FE76A2", "#FFFFFF", "#BF12D7", "#000000", "#303CBE"],
|
||||
"bisexual": ["#D60270", "#9B4F96", "#0038A8"],
|
||||
"pansexual": ["#FF1C8D", "#FFD700", "#1AB3FF"],
|
||||
"polysexual": ["#F714BA", "#01D66A", "#1594F6"],
|
||||
"omnisexual": {
|
||||
"colors": ["#FE9ACE", "#FF53BF", "#200044", "#6760FE", "#8EA6FF"],
|
||||
"comment": "omnisexual sorced from https://www.flagcolorcodes.com/omnisexual"
|
||||
},
|
||||
"omniromantic": ["#FEC8E4", "#FDA1DB", "#89739A", "#ABA7FE", "#BFCEFF"],
|
||||
"gay-men": {
|
||||
"colors": ["#078D70", "#98E8C1", "#FFFFFF", "#7BADE2", "#3D1A78"],
|
||||
"comment": "gay men sourced from https://www.flagcolorcodes.com/gay-men"
|
||||
},
|
||||
"lesbian": ["#D62800", "#FF9B56", "#FFFFFF", "#D462A6", "#A40062"],
|
||||
"abrosexual": {
|
||||
"colors": ["#46D294", "#A3E9CA", "#FFFFFF", "#F78BB3", "#EE1766"],
|
||||
"comment": "abrosexual used colorpicker to source from https://fyeahaltpride.tumblr.com/post/151704251345/could-you-guys-possibly-make-an-abrosexual-pride"
|
||||
},
|
||||
"asexual": ["#000000", "#A4A4A4", "#FFFFFF", "#810081"],
|
||||
"aromantic": ["#3BA740", "#A8D47A", "#FFFFFF", "#ABABAB", "#000000"],
|
||||
"fictosexual": {
|
||||
"colors": ["#000000", "#C4C4C4", "#A349A5", "#C4C4C4", "#000000"],
|
||||
"comment": "https://orientation.fandom.com/wiki/Fictosexual"
|
||||
},
|
||||
"aroace1": {
|
||||
"colors": ["#E28C00", "#ECCD00", "#FFFFFF", "#62AEDC", "#203856"],
|
||||
"comment": "aroace1 sourced from https://flag.library.lgbt/flags/aroace/"
|
||||
},
|
||||
"aroace2": ["#000000", "#810081", "#A4A4A4", "#FFFFFF", "#A8D47A", "#3BA740"],
|
||||
"aroace3": ["#3BA740", "#A8D47A", "#FFFFFF", "#ABABAB", "#000000", "#A4A4A4", "#FFFFFF", "#810081"],
|
||||
"autosexual": ["#99D9EA", "#7F7F7F"],
|
||||
"intergender": {
|
||||
"colors": ["#900DC2", "#900DC2", "#FFE54F", "#900DC2", "#900DC2"],
|
||||
"comment": "todo: use weighted spacing"
|
||||
},
|
||||
"greygender": ["#B3B3B3", "#B3B3B3", "#FFFFFF", "#062383", "#062383", "#FFFFFF", "#535353", "#535353"],
|
||||
"akiosexual": ["#F9485E", "#FEA06A", "#FEF44C", "#FFFFFF", "#000000"],
|
||||
"bigender": {
|
||||
"colors": ["#C479A2", "#EDA5CD", "#D6C7E8", "#FFFFFF", "#D6C7E8", "#9AC7E8", "#6D82D1"],
|
||||
"comment": "bigender sourced from https://www.flagcolorcodes.com/bigender"
|
||||
},
|
||||
"demigender": {
|
||||
"colors": ["#7F7F7F", "#C4C4C4", "#FBFF75", "#FFFFFF", "#FBFF75", "#C4C4C4", "#7F7F7F"],
|
||||
"comment": "demigender yellow sourced from https://lgbtqia.fandom.com/f/p/4400000000000041031 other colors sourced from demiboy and demigirl flags"
|
||||
},
|
||||
"demiboy": {
|
||||
"colors": ["#7F7F7F", "#C4C4C4", "#9DD7EA", "#FFFFFF", "#9DD7EA", "#C4C4C4", "#7F7F7F"],
|
||||
"comment": "demiboy sourced from https://www.flagcolorcodes.com/demiboy"
|
||||
},
|
||||
"demigirl": {
|
||||
"colors": ["#7F7F7F", "#C4C4C4", "#FDADC8", "#FFFFFF", "#FDADC8", "#C4C4C4", "#7F7F7F"],
|
||||
"comment": "demigirl sourced from https://www.flagcolorcodes.com/demigirl"
|
||||
},
|
||||
"transmasculine": ["#FF8ABD", "#CDF5FE", "#9AEBFF", "#74DFFF", "#9AEBFF", "#CDF5FE", "#FF8ABD"],
|
||||
"transfeminine": {
|
||||
"colors": ["#73DEFF", "#FFE2EE", "#FFB5D6", "#FF8DC0", "#FFB5D6", "#FFE2EE", "#73DEFF"],
|
||||
"comment": "transfeminine used colorpicker to source from https://www.deviantart.com/pride-flags/art/Trans-Woman-Transfeminine-1-543925985 linked from https://gender.fandom.com/wiki/Transfeminine"
|
||||
},
|
||||
"genderfaun": {
|
||||
"colors": ["#FCD689", "#FFF09B", "#FAF9CD", "#FFFFFF", "#8EDED9", "#8CACDE", "#9782EC"],
|
||||
"comment": "genderfaun sourced from https://www.flagcolorcodes.com/genderfaun"
|
||||
},
|
||||
"demifaun": ["#7F7F7F", "#7F7F7F", "#C6C6C6", "#C6C6C6", "#FCC688", "#FFF19C", "#FFFFFF", "#8DE0D5", "#9682EC", "#C6C6C6", "#C6C6C6", "#7F7F7F", "#7F7F7F"],
|
||||
"genderfae": {
|
||||
"colors": ["#97C3A5", "#C3DEAE", "#F9FACD", "#FFFFFF", "#FCA2C4", "#DB8AE4", "#A97EDD"],
|
||||
"comment": "genderfae sourced from https://www.flagcolorcodes.com/genderfae"
|
||||
},
|
||||
"demifae": {
|
||||
"colors": ["#7F7F7F", "#7F7F7F", "#C5C5C5", "#C5C5C5", "#97C3A4", "#C4DEAE", "#FFFFFF", "#FCA2C5", "#AB7EDF", "#C5C5C5", "#C5C5C5", "#7F7F7F", "#7F7F7F"],
|
||||
"comment": "demifae used colorpicker to source form https://www.deviantart.com/pride-flags/art/Demifae-870194777"
|
||||
},
|
||||
"neutrois": ["#FFFFFF", "#1F9F00", "#000000"],
|
||||
"biromantic1": ["#8869A5", "#D8A7D8", "#FFFFFF", "#FDB18D", "#151638"],
|
||||
"biromantic2": ["#740194", "#AEB1AA", "#FFFFFF", "#AEB1AA", "#740194"],
|
||||
"autoromantic": {
|
||||
"colors": ["#99D9EA", "#99D9EA", "#3DA542", "#7F7F7F", "#7F7F7F"],
|
||||
"comment": "symbol interpreted"
|
||||
},
|
||||
"boyflux2": {
|
||||
"colors": ["#E48AE4", "#9A81B4", "#55BFAB", "#FFFFFF", "#A8A8A8", "#81D5EF", "#69ABE5", "#5276D4"],
|
||||
"weights": [1, 1, 1, 1, 1, 5, 5, 5]
|
||||
},
|
||||
"girlflux": {
|
||||
"colors": ["#F9E6D7", "#F2526C", "#BF0311", "#E9C587", "#BF0311", "#F2526C", "#F9E6D7"],
|
||||
"comment": "sourced from https://commons.wikimedia.org/wiki/File:Girlflux_Pride_Flag.jpg"
|
||||
},
|
||||
"genderflux": {
|
||||
"colors": ["#F47694", "#F2A2B9", "#CECECE", "#7CE0F7", "#3ECDF9", "#FFF48D"],
|
||||
"comment": "sourced from https://www.deviantart.com/pride-flags/art/Genderflux-1-543925589"
|
||||
},
|
||||
"nullflux": {
|
||||
"colors": ["#0B0C0E", "#A28DB9", "#E1D4EF", "#F0E6DD", "#665858"],
|
||||
"comment": "https://lgbtqia.wiki/wiki/Gendernull"
|
||||
},
|
||||
"hypergender": ["#EFEFEF", "#FFFFFF", "#FBFF75", "#000000", "#FBFF75", "#FFFFFF", "#EFEFEF"],
|
||||
"hyperboy": ["#EFEFEF", "#FFFFFF", "#74D7FE", "#000000", "#74D7FE", "#FFFFFF", "#EFEFEF"],
|
||||
"hypergirl": ["#EFEFEF", "#FFFFFF", "#FC76D3", "#000000", "#FC76D3", "#FFFFFF", "#EFEFEF"],
|
||||
"hyperandrogyne": ["#EFEFEF", "#FFFFFF", "#BB83FF", "#000000", "#BB83FF", "#FFFFFF", "#EFEFEF"],
|
||||
"hyperneutrois": ["#EFEFEF", "#FFFFFF", "#BAFA74", "#000000", "#BAFA74", "#FFFFFF", "#EFEFEF"],
|
||||
"finsexual": ["#B18EDF", "#D7B1E2", "#F7CDE9", "#F39FCE", "#EA7BB3"],
|
||||
"unlabeled1": ["#EAF8E4", "#FDFDFB", "#E1EFF7", "#F4E2C4"],
|
||||
"unlabeled2": ["#250548", "#FFFFFF", "#F7DCDA", "#EC9BEE", "#9541FA", "#7D2557"],
|
||||
"pangender": ["#FFF798", "#FEDDCD", "#FFEBFB", "#FFFFFF", "#FFEBFB", "#FEDDCD", "#FFF798"],
|
||||
"pangender.contrast": ["#FFE87F", "#FCBAA6", "#FBC9F3", "#FFFFFF", "#FBC9F3", "#FCBAA6", "#FFE87F"],
|
||||
"gendernonconforming1": {
|
||||
"colors": ["#50284D", "#96467B", "#5C96F7", "#FFE6F7", "#5C96F7", "#96467B", "#50284D"],
|
||||
"weights": [4, 1, 1, 1, 1, 1, 4]
|
||||
},
|
||||
"gendernonconforming2": ["#50284D", "#96467B", "#5C96F7", "#FFE6F7", "#5C96F7", "#96467B", "#50284D"],
|
||||
"femboy": ["#D260A5", "#E4AFCD", "#FEFEFE", "#57CEF8", "#FEFEFE", "#E4AFCD", "#D260A5"],
|
||||
"tomboy": ["#2F3FB9", "#613A03", "#FEFEFE", "#F1A9B7", "#FEFEFE", "#613A03", "#2F3FB9"],
|
||||
"gynesexual": ["#F4A9B7", "#903F2B", "#5B953B"],
|
||||
"androsexual": ["#01CCFF", "#603524", "#B799DE"],
|
||||
"gendervoid": {
|
||||
"colors": ["#081149", "#4B484B", "#000000", "#4B484B", "#081149"],
|
||||
"comment": "gendervoid and related flags sourced from: https://gender.fandom.com/wiki/Gendervoid"
|
||||
},
|
||||
"voidgirl": ["#180827", "#7A5A8B", "#E09BED", "#7A5A8B", "#180827"],
|
||||
"voidboy": ["#0B130C", "#547655", "#66B969", "#547655", "#0B130C"],
|
||||
"nonhuman-unity": {
|
||||
"colors": ["#177B49", "#FFFFFF", "#593C90"],
|
||||
"comment": "used https://twitter.com/foxbrained/status/1667621855518236674/photo/1 as source and colorpicked"
|
||||
},
|
||||
"plural": {
|
||||
"colors": ["#2D0625", "#543475", "#7675C3", "#89C7B0", "#F3EDBD"],
|
||||
"comment": "used https://pluralpedia.org/w/Plurality#/media/File:Plural-Flag-1.jpg as source and colorpicked"
|
||||
},
|
||||
"fraysexual": {
|
||||
"colors": ["#226CB5", "#94E7DD", "#FFFFFF", "#636363"],
|
||||
"comment": "sampled from https://es.m.wikipedia.org/wiki/Archivo:Fraysexual_flag.jpg"
|
||||
},
|
||||
"bear": {
|
||||
"colors": ["#623804", "#D56300", "#FEDD63", "#FEE6B8", "#FFFFFF", "#555555"],
|
||||
"comment": "sourced from https://commons.wikimedia.org/wiki/File:Bear_Brotherhood_flag.svg"
|
||||
},
|
||||
"butch": {
|
||||
"colors": ["#D72800", "#F17623", "#FF9C56", "#FFFDF6", "#FFCE89", "#FEAF02", "#A37000"],
|
||||
"comment": "colorpicked from https://commons.wikimedia.org/wiki/File:Butch_Flag.png"
|
||||
},
|
||||
"leather": {
|
||||
"colors": ["#000000", "#252580", "#000000", "#252580", "#FFFFFF", "#252580", "#000000", "#252580", "#000000"],
|
||||
"comment": "colorpicked from https://commons.wikimedia.org/wiki/File:Leather,_Latex,_and_BDSM_pride_-_Light.svg"
|
||||
},
|
||||
"otter": {
|
||||
"colors": ["#263881", "#5C9DC9", "#FFFFFF", "#3A291D", "#5C9DC9", "#263881"],
|
||||
"comment": "colorpicked from https://commons.wikimedia.org/wiki/File:Official_Otter_Pride_Flag_by_Bearbackgear.jpg"
|
||||
},
|
||||
"twink": {
|
||||
"colors": ["#FFB2FF", "#FFFFFF", "#FFFF81"],
|
||||
"comment": "colorpicked from https://commons.wikimedia.org/wiki/File:Twink_Pride_Flag_(proposed).svg"
|
||||
},
|
||||
"adipophilia": {
|
||||
"colors": ["#000000", "#E16180", "#FFF9BE", "#603E41", "#000000"],
|
||||
"comment": "https://en.wikipedia.org/wiki/File:FatFetishFlag.png"
|
||||
},
|
||||
"kenochoric": ["#000000", "#2E1569", "#824DB7", "#C7A1D6"],
|
||||
"veldian": ["#D182A8", "#FAF6E0", "#69ACBE", "#5D448F", "#3A113E"],
|
||||
"solian": ["#FFF8ED", "#FFE7A8", "#F1B870", "#A56058", "#46281E"],
|
||||
"lunian": ["#2F0E62", "#6F41B1", "#889FDF", "#7DDFD5", "#D2F2E2"],
|
||||
"polyam": {
|
||||
"colors": ["#FFFFFF", "#FCBF00", "#009FE3", "#E50051", "#340C46"],
|
||||
"comment": "polyamorous flag colors pulled from https://polyamproud.com/flag"
|
||||
},
|
||||
"sapphic": ["#FD8BA8", "#FBF2FF", "#C76BC5", "#FDD768", "#C76BC5", "#FBF2FF", "#FD8BA8"],
|
||||
"androgyne": ["#FE007F", "#9832FF", "#00B8E7"],
|
||||
"interprogress": ["#FFD800", "#7902AA", "#FFFFFF", "#FFAFC8", "#74D7EE", "#613915", "#000000", "#E50000", "#FF8D00", "#FFEE00", "#028121", "#004CFF", "#770088"],
|
||||
"progress": ["#FFFFFF", "#FFAFC8", "#74D7EE", "#613915", "#000000", "#E50000", "#FF8D00", "#FFEE00", "#028121", "#004CFF", "#770088"],
|
||||
"intersex": ["#FFD800", "#FFD800", "#7902AA", "#FFD800", "#FFD800"],
|
||||
"old-polyam": ["#0000FF", "#FF0000", "#FFFF00", "#FF0000", "#000000"],
|
||||
"equal-rights": ["#0000FF", "#0000FF", "#FFFF00", "#0000FF", "#0000FF", "#FFFF00", "#0000FF", "#0000FF"],
|
||||
"drag": ["#CC67FF", "#FFFFFF", "#FFA3E3", "#FFFFFF", "#3366FF"],
|
||||
"pronounfluid": ["#FFB3F9", "#FFFFFF", "#D1FDCB", "#C7B0FF", "#000000", "#B8CCFF"],
|
||||
"pronounflux": ["#FDB3F8", "#B6CCFA", "#18DDD3", "#64FF89", "#FF7690", "#FFFFFF"],
|
||||
"exipronoun": ["#1C3D34", "#FFFFFF", "#321848", "#000000"],
|
||||
"neopronoun": ["#BCEC64", "#FFFFFF", "#38077A"],
|
||||
"neofluid": ["#FFECA0", "#FFFFFF", "#FFECA0", "#38087A", "#BCEC64"],
|
||||
"genderqueer": ["#B57EDC", "#B57EDC", "#FFFFFF", "#FFFFFF", "#4A8123", "#4A8123"],
|
||||
"cisgender": ["#D70270", "#0038A7"],
|
||||
"baker": {
|
||||
"colors": ["#F23D9E", "#F80A24", "#F78022", "#F9E81F", "#1E972E", "#1B86BC", "#243897", "#6F0A82"],
|
||||
"comment": "colors from Gilbert Baker's original 1978 flag design used https://gilbertbaker.com/rainbow-flag-color-meanings/ as source and colorpicked"
|
||||
},
|
||||
"caninekin": {
|
||||
"colors": ["#2D2822", "#543D25", "#9C754D", "#E8DAC2", "#CFAD8C", "#B77B55", "#954E31"],
|
||||
"comment": "this is 4 all the dogs, from zombpawcoins on tumblr!"
|
||||
},
|
||||
"libragender": {
|
||||
"colors": ["#000000", "#808080", "#92D8E9", "#FFF544", "#FFB0CA", "#808080", "#000000"],
|
||||
"comment": "Sourced from https://lgbtqia.wiki/wiki/Libragender"
|
||||
},
|
||||
"librafeminine": {
|
||||
"colors": ["#000000", "#A3A3A3", "#FFFFFF", "#C6568F", "#FFFFFF", "#A3A3A3", "#000000"],
|
||||
"comment": "Sourced from https://lgbtqia.wiki/wiki/Librafeminine"
|
||||
},
|
||||
"libramasculine": {
|
||||
"colors": ["#000000", "#A3A3A3", "#FFFFFF", "#56C5C5", "#FFFFFF", "#A3A3A3", "#000000"],
|
||||
"comment": "Sourced from https://lgbtqia.wiki/wiki/Libramasculine"
|
||||
},
|
||||
"libraandrogyne": {
|
||||
"colors": ["#000000", "#A3A3A3", "#FFFFFF", "#9186B1", "#FFFFFF", "#A3A3A3", "#000000"],
|
||||
"comment": "Sourced from https://lgbtqia.wiki/wiki/Librandrogyne"
|
||||
},
|
||||
"libranonbinary": {
|
||||
"colors": ["#000000", "#A3A3A3", "#FFFFFF", "#FFF987", "#FFFFFF", "#A3A3A3", "#000000"],
|
||||
"comment": "Sourced from https://lgbtqia.wiki/wiki/Libranonbinary"
|
||||
},
|
||||
"fluidflux1": {
|
||||
"colors": ["#FF115F", "#A34AA3", "#00A4E7", "#FFDF00", "#000000", "#FFED71", "#85DAFF", "#DBADDA", "#FE8DB1"],
|
||||
"comment": "Sourced from https://gender.fandom.com/wiki/Fluidflux?file=FC90B24D-CA36-4FE2-A752-C9ABFC65E332.jpeg"
|
||||
},
|
||||
"fluidflux2": ["#C6D1D2", "#F47B9D", "#F09F9B", "#E3F09E", "#75EEEA", "#52D2ED", "#C6D1D2"],
|
||||
|
||||
"beiyang": ["#DF1B12", "#FFC600", "#01639D", "#FFFFFF", "#000000"],
|
||||
"burger": ["#F3A26A", "#498701", "#FD1C13", "#7D3829", "#F3A26A"],
|
||||
"throatlozenges": ["#2759DA", "#03940D", "#F5F100", "#F59B00", "#B71212"],
|
||||
"band": ["#2670C0", "#F5BD00", "#DC0045", "#E0608E"]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
# This file is automatically generated. Please do not modify.
|
||||
|
||||
from . import AsciiArt
|
||||
|
||||
bazzite = AsciiArt(match=r'''"Bazzite"*''', color='5 5', ascii=r"""
|
||||
${c1} %%%%%%====%%%%%%%%%%
|
||||
%%%%%%%% %%%%%%%%%%%%%%
|
||||
%%%%%%%%% %%%%%%%%%%%%%%%%
|
||||
%%%%%%%%% %%%%%%%%%%%%%%%###
|
||||
%%%%%%%%% %%%%%%%%%%%%%######
|
||||
== =======######
|
||||
== =========#####
|
||||
%%%%%%%%% %%%%%%%####======#####
|
||||
%%%%%%%%% %%%%%#######=====#####
|
||||
%%%%%%%%% %%%#########=====#####
|
||||
%%%%%%%%% %%##########=====#####
|
||||
%%%%%%%%%====###########=====######
|
||||
%%%%%%%%====#########======######
|
||||
%%%%%%%=====#####========######
|
||||
%%%%###===============#######
|
||||
%#######==========#########
|
||||
#######################
|
||||
###################
|
||||
###########
|
||||
""")
|
||||
|
||||
@@ -208,6 +208,10 @@ def detect(name: str) -> AsciiArt | None:
|
||||
from .bedrock import bedrock
|
||||
return bedrock
|
||||
|
||||
if name.startswith('bazzite'):
|
||||
from .bazzite import bazzite
|
||||
return bazzite
|
||||
|
||||
if name.startswith('biglinux_large'):
|
||||
from .biglinux_large import biglinux_large
|
||||
return biglinux_large
|
||||
@@ -664,9 +668,9 @@ def detect(name: str) -> AsciiArt | None:
|
||||
from .interix import interix
|
||||
return interix
|
||||
|
||||
if name.startswith('ironclad'):
|
||||
from .ironclad import ironclad
|
||||
return ironclad
|
||||
if name.startswith('gloire'):
|
||||
from .gloire import gloire
|
||||
return gloire
|
||||
|
||||
if name.startswith('januslinux') or name.startswith('janus') or name.startswith('ataraxia linux') or name.startswith('ataraxia'):
|
||||
from .januslinux import januslinux
|
||||
@@ -1180,6 +1184,10 @@ def detect(name: str) -> AsciiArt | None:
|
||||
from .rhaymos import rhaymos
|
||||
return rhaymos
|
||||
|
||||
if name.startswith('rhino linux'):
|
||||
from .rhino_linux import rhino_linux
|
||||
return rhino_linux
|
||||
|
||||
if name.startswith('rocky_small'):
|
||||
from .rocky_small import rocky_small
|
||||
return rocky_small
|
||||
@@ -1312,6 +1320,10 @@ def detect(name: str) -> AsciiArt | None:
|
||||
from .t2 import t2
|
||||
return t2
|
||||
|
||||
if name.startswith('opensuse tumbleweed-slowroll') or name.startswith('opensuse_slowroll'):
|
||||
from .opensuse_tumbleweed_slowroll import opensuse_tumbleweed_slowroll
|
||||
return opensuse_tumbleweed_slowroll
|
||||
|
||||
if name.startswith('opensuse tumbleweed') or name.startswith('opensuse_tumbleweed'):
|
||||
from .opensuse_tumbleweed import opensuse_tumbleweed
|
||||
return opensuse_tumbleweed
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# This file is automatically generated. Please do not modify.
|
||||
|
||||
from . import AsciiArt
|
||||
|
||||
gloire = AsciiArt(match=r'''"Gloire"*''', color='5 7 0', ascii=r"""
|
||||
${c3}
|
||||
&#BGPPPPPG#&
|
||||
B5?77!!?YJJ7!7YBB&
|
||||
&G5YJ77!7JYYYYYBPJ&PY#
|
||||
#PYYYYYY?!?YYYYY7?7JP5JJ
|
||||
B?YYYYYY7!!7JYYYYJ!!?JJJ5
|
||||
&& B7?J?77?7!!!!!77777!7Y5YYBBPGGG&
|
||||
G77?YBB!!!!!!!!!!!!!JYJ??7JYJJY# PYPPG&
|
||||
J777JB?!7JJ???!!!7?JYYYYYPJ!7JB
|
||||
GYYG #JJJJJ??7!!!JYYY5PGB&GB&
|
||||
#Y!?GB5YYJY5PG###&
|
||||
GJJP
|
||||
""")
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
from . import AsciiArt
|
||||
|
||||
nixos_small = AsciiArt(match=r'''"nixos_small"''', color='4 6', ascii=r"""
|
||||
${c1} \\ \\ //
|
||||
${c1} \\ \\ //
|
||||
==\\__\\/ //
|
||||
// \\//
|
||||
==// //==
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# This file is automatically generated. Please do not modify.
|
||||
|
||||
from . import AsciiArt
|
||||
|
||||
opensuse_tumbleweed_slowroll = AsciiArt(match=r'''"openSUSE Tumbleweed-Slowroll"* | "openSUSE_Slowroll"*''', color='2 7', ascii=r"""
|
||||
${c2} _aaaymQQmwaaa,
|
||||
,wWQQQD????????$QQQQa,.
|
||||
_wQQB?" ??QQQa,
|
||||
sQQD^ ?QQ6\
|
||||
yWW' 4QQg
|
||||
,QQD .aaaaaaaa ^4Q6
|
||||
,mQP _wWQW?????YWWQa, 4Qm
|
||||
jQ@ wWW?' ^4QQc ^$QL
|
||||
,QQ' jWW' )QW\ ]QQ
|
||||
|QQ ,QW' ]QQ ^QQ|
|
||||
|QQ |QQ ]QQ QQ|
|
||||
|QQ 4Qg ]QQ .QQ|
|
||||
'QQ6 '$WQac. _QQ( jQQ
|
||||
]QQw "?QWQQf _mQP ,QQ(
|
||||
4QQga wQQP ,mQ?
|
||||
4QQQga, saQWP' jQQf
|
||||
?QQQQQQwaaaaaaaayWWW?' _mQ@'
|
||||
?WQQQP?9VWUV???^ _amQP^
|
||||
"4QQQaa, ,awQQQ?^
|
||||
"?VQQQQQQQQQQQQQQP?'
|
||||
""")
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# This file is automatically generated. Please do not modify.
|
||||
|
||||
from . import AsciiArt
|
||||
|
||||
rhino_linux = AsciiArt(match=r'''"Rhino Linux"*''', color='5 4', ascii=r"""
|
||||
${c1}
|
||||
${c1} ..','.. l.
|
||||
.,coooooooooc,..ool
|
||||
;oooooooooooooooooooo.,coo.
|
||||
;oooooooooooooooooooooooooo ,
|
||||
.ooooooooooooooooooooooooooo . ,o
|
||||
oollcccccccccllloooooooooooolcoo..oo
|
||||
ll;':::::::::::::::ccloooooooooooooo:
|
||||
.;''';::::::::::::::::::ccloooooooooo
|
||||
''''',:::::::::::::::::::::::cclllllc
|
||||
'''''';::::::::::::::::::::::::::::::
|
||||
${c1}.'''''';::::::::::::::::${c2}ll${c1}:::::::::::
|
||||
${c1} ''''''';:::::::::::::::${c2}d0${c1}::
|
||||
${c1}.''''''',;:::::::${c2}cc${c1}::::${c2}0N:'
|
||||
${c1}''''''''',,;::::${c2}cK${c1}:::${c2}dMX,
|
||||
${c1}'''''''''''',,,${c2}dMccOMM${c1}:
|
||||
${c1}.''''''''''''${c2}cWM0WMM${c1}.
|
||||
${c1}'''''''':${c2}kMMMMM${c1}.
|
||||
${c2}odxONMMMM
|
||||
;Kl
|
||||
""")
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
from __future__ import annotations
|
||||
|
||||
from hyfetch.constants import CACHE_PATH
|
||||
from hyfetch.neofetch_util import get_distro_name
|
||||
import json
|
||||
|
||||
from .constants import CACHE_PATH, SRC
|
||||
from .neofetch_util import get_distro_name
|
||||
|
||||
|
||||
def get_font_logo() -> str:
|
||||
@@ -10,7 +11,7 @@ def get_font_logo() -> str:
|
||||
if cache.exists():
|
||||
return cache.read_text('utf-8')
|
||||
|
||||
font_logos: dict[str, str] = json.loads((Path(__file__).parent / 'data/font_logos.json').read_text('utf-8'))
|
||||
font_logos: dict[str, str] = json.loads((SRC / 'data/font_logos.json').read_text('utf-8'))
|
||||
font_logos = {k.lower(): v for k, v in font_logos.items()}
|
||||
|
||||
# Get the distro
|
||||
|
||||
+75
-13
@@ -5,9 +5,10 @@ import argparse
|
||||
import datetime
|
||||
import importlib.util
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import traceback
|
||||
from itertools import permutations
|
||||
from itertools import permutations, islice
|
||||
from math import ceil
|
||||
|
||||
from . import termenv, neofetch_util, pride_month
|
||||
@@ -17,7 +18,7 @@ from .constants import *
|
||||
from .font_logo import get_font_logo
|
||||
from .models import Config
|
||||
from .neofetch_util import *
|
||||
from .presets import PRESETS
|
||||
from .presets import PRESETS, ColorProfile
|
||||
|
||||
|
||||
def check_config(path) -> Config:
|
||||
@@ -251,7 +252,7 @@ def create_config() -> Config:
|
||||
slots = list(set(map(int, re.findall('(?<=\\${c)[0-9](?=})', asc))))
|
||||
while len(pis) < len(slots):
|
||||
pis += pis
|
||||
perm = {p[:len(slots)] for p in permutations(pis)}
|
||||
perm = {p[:len(slots)] for p in islice(permutations(pis), 1000)}
|
||||
random_count = max(0, ascii_per_row * ascii_rows - len(arrangements))
|
||||
if random_count > len(perm):
|
||||
choices = perm
|
||||
@@ -309,7 +310,7 @@ def create_config() -> Config:
|
||||
printc('- &bqwqfetch&r: Pure python, &nminimal dependencies&r ' +
|
||||
('&c(Not installed)' if not has_qwqfetch else ''))
|
||||
print()
|
||||
|
||||
|
||||
# Use fastfetch as the default backend if it is installed
|
||||
def_backend = 'neofetch' if ff_path is None else 'fastfetch'
|
||||
|
||||
@@ -318,9 +319,49 @@ def create_config() -> Config:
|
||||
backend = select_backend()
|
||||
update_title('Selected backend', backend)
|
||||
|
||||
##############################
|
||||
# 7. Custom ASCII file
|
||||
custom_ascii_path = None
|
||||
clear_screen(title)
|
||||
if literal_input('Do you want to specify a custom ASCII file?', ['y', 'n'], 'n') == 'y':
|
||||
while True:
|
||||
path_input = input('Path to custom ASCII file (must be .txt and UTF-8 encoded): ').strip()
|
||||
if not path_input:
|
||||
printc('&cNo path entered. Skipping custom ASCII file.')
|
||||
break
|
||||
|
||||
custom_path = Path(path_input)
|
||||
if not custom_path.is_file():
|
||||
printc(f'&cError: File not found at {path_input}')
|
||||
if literal_input('Try again?', ['y', 'n'], 'y') == 'n':
|
||||
break
|
||||
continue
|
||||
|
||||
if not custom_path.suffix == '.txt':
|
||||
printc(f'&cError: File must have a .txt extension. Found {custom_path.suffix}')
|
||||
if literal_input('Try again?', ['y', 'n'], 'y') == 'n':
|
||||
break
|
||||
continue
|
||||
|
||||
try:
|
||||
custom_path.read_text('utf-8')
|
||||
custom_ascii_path = str(custom_path)
|
||||
update_title('Custom ASCII file', custom_ascii_path)
|
||||
break
|
||||
except UnicodeDecodeError:
|
||||
printc(f'&cError: File is not UTF-8 encoded.')
|
||||
if literal_input('Try again?', ['y', 'n'], 'y') == 'n':
|
||||
break
|
||||
continue
|
||||
except Exception as e:
|
||||
printc(f'&cAn unexpected error occurred: {e}')
|
||||
if literal_input('Try again?', ['y', 'n'], 'y') == 'n':
|
||||
break
|
||||
continue
|
||||
|
||||
# Create config
|
||||
clear_screen(title)
|
||||
c = Config(preset, color_system, light_dark, lightness, color_alignment, backend)
|
||||
c = Config(preset, color_system, light_dark, lightness, color_alignment, backend, custom_ascii_path=custom_ascii_path)
|
||||
|
||||
# Save config
|
||||
print()
|
||||
@@ -338,7 +379,7 @@ def create_parser() -> argparse.ArgumentParser:
|
||||
|
||||
parser.add_argument('-c', '--config', action='store_true', help=color(f'Configure hyfetch'))
|
||||
parser.add_argument('-C', '--config-file', dest='config_file', default=CONFIG_PATH, help=f'Use another config file')
|
||||
parser.add_argument('-p', '--preset', help=f'Use preset', choices=list(PRESETS.keys()) + ['random'])
|
||||
parser.add_argument('-p', '--preset', help=f'Use preset or comma-separated hex color list (e.g., "#ff0000,#00ff00,#0000ff")')
|
||||
parser.add_argument('-m', '--mode', help=f'Color mode', choices=['8bit', 'rgb'])
|
||||
parser.add_argument('-b', '--backend', help=f'Choose a *fetch backend', choices=['qwqfetch', 'neofetch', 'fastfetch', 'fastfetch-old'])
|
||||
parser.add_argument('--args', help=f'Additional arguments pass-through to backend')
|
||||
@@ -382,7 +423,7 @@ def run():
|
||||
GLOBAL_CFG.use_overlay = args.overlay
|
||||
|
||||
if args.version:
|
||||
print(f'Version is {VERSION}')
|
||||
print(f'Version is 1.99.∞\n(python hyfetch legacy mode)')
|
||||
return
|
||||
|
||||
# Ensure git bash for windows
|
||||
@@ -414,17 +455,18 @@ def run():
|
||||
# Check if it's June (pride month)
|
||||
now = datetime.datetime.now()
|
||||
june_path = CACHE_PATH / f'animation-displayed-{now.year}'
|
||||
show_for_june = False
|
||||
if now.month == 6 and now.year not in config.pride_month_shown and not june_path.is_file() and os.isatty(sys.stdout.fileno()):
|
||||
args.june = True
|
||||
show_for_june = True
|
||||
|
||||
if args.june and not config.pride_month_disable:
|
||||
if (args.june or show_for_june) and not config.pride_month_disable:
|
||||
pride_month.start_animation()
|
||||
print()
|
||||
print("Happy pride month!")
|
||||
print("(You can always view the animation again with `hyfetch --june`)")
|
||||
print()
|
||||
|
||||
if not june_path.is_file():
|
||||
if not june_path.is_file() and not args.june: # If --june wasn't explicitly specified...
|
||||
june_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
june_path.touch()
|
||||
|
||||
@@ -440,7 +482,7 @@ def run():
|
||||
config.backend = args.backend
|
||||
if args.args:
|
||||
config.args = args.args
|
||||
|
||||
|
||||
# Random preset
|
||||
if config.preset == 'random':
|
||||
config.preset = random.choice(list(PRESETS.keys()))
|
||||
@@ -450,7 +492,21 @@ def run():
|
||||
GLOBAL_CFG.is_light = config.light_dark == 'light'
|
||||
|
||||
# Get preset
|
||||
preset = PRESETS.get(config.preset)
|
||||
preset = None
|
||||
if config.preset in PRESETS:
|
||||
preset = PRESETS.get(config.preset)
|
||||
elif '#' in config.preset:
|
||||
colors = [color.strip() for color in config.preset.split(',')]
|
||||
|
||||
for color in colors:
|
||||
if not (color.startswith('#') and len(color) in [4, 7] and all(c in '0123456789abcdefABCDEF' for c in color[1:])):
|
||||
print(f'Error: invalid hex color "{color}"')
|
||||
preset = ColorProfile(colors)
|
||||
else:
|
||||
print(f'Preset should be a comma-separated list of hex colors, or one of the following: {", ".join(sorted(PRESETS.keys()))}')
|
||||
|
||||
if preset is None:
|
||||
exit(1)
|
||||
|
||||
# Lighten (args > config)
|
||||
if args.scale:
|
||||
@@ -462,8 +518,14 @@ def run():
|
||||
|
||||
# Run
|
||||
try:
|
||||
asc = get_distro_ascii() if not args.ascii_file else Path(args.ascii_file).read_text("utf-8")
|
||||
if config.custom_ascii_path:
|
||||
asc = Path(config.custom_ascii_path).read_text("utf-8")
|
||||
elif args.ascii_file:
|
||||
asc = Path(args.ascii_file).read_text("utf-8")
|
||||
else:
|
||||
asc = get_distro_ascii()
|
||||
asc = config.color_align.recolor_ascii(asc, preset)
|
||||
asc = '\n'.join(asc.split('\n')[1:])
|
||||
neofetch_util.run(asc, config.backend, config.args or '')
|
||||
except Exception as e:
|
||||
print(f'Error: {e}')
|
||||
|
||||
@@ -20,6 +20,7 @@ class Config:
|
||||
distro: str | None = None
|
||||
pride_month_shown: list[int] = field(default_factory=list) # This is deprecated, see issue #136
|
||||
pride_month_disable: bool = False
|
||||
custom_ascii_path: str | None = None
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, d: dict):
|
||||
|
||||
@@ -14,14 +14,13 @@ from tempfile import TemporaryDirectory
|
||||
from typing import Iterable
|
||||
|
||||
from .color_util import color, printc
|
||||
from .constants import GLOBAL_CFG, IS_WINDOWS
|
||||
from .constants import GLOBAL_CFG, IS_WINDOWS, SRC
|
||||
from .distros import distro_detector
|
||||
from .presets import ColorProfile
|
||||
from .serializer import from_dict
|
||||
from .types import BackendLiteral, ColorAlignMode
|
||||
|
||||
RE_NEOFETCH_COLOR = re.compile('\\${c[0-9]}')
|
||||
SRC = Path(__file__).parent
|
||||
|
||||
|
||||
def literal_input(prompt: str, options: Iterable[str], default: str, show_ops: bool = True) -> str:
|
||||
@@ -333,7 +332,7 @@ def run_qwqfetch(asc: str, args: str = ''):
|
||||
import qwqfetch
|
||||
# distro_detector only return a bash variable
|
||||
# so we use qwqfetch builtin distro detector
|
||||
print(qwqfetch.get_ascres(asc))
|
||||
print(qwqfetch.get_ascres(asc))
|
||||
except ImportError as e: # module not found etc
|
||||
print("qwqfetch is not installed. Install it by executing:") # use print to output hint directly
|
||||
print("pip install git+https://github.com/nexplorer-3e/qwqfetch") # TODO: public repo
|
||||
@@ -379,17 +378,19 @@ def run_fastfetch(asc: str, args: str = '', legacy: bool = False):
|
||||
"""
|
||||
# Find fastfetch binary
|
||||
ff_path = fastfetch_path()
|
||||
|
||||
|
||||
if not ff_path:
|
||||
printc("&cError: fastfetch binary is not found. Please install fastfetch first.")
|
||||
exit(127)
|
||||
|
||||
|
||||
# Write temp file
|
||||
with TemporaryDirectory() as tmp_dir:
|
||||
tmp_dir = Path(tmp_dir)
|
||||
path = tmp_dir / 'ascii.txt'
|
||||
path.write_text(asc, 'utf-8')
|
||||
|
||||
os.environ['FFTS_IGNORE_PARENT'] = '1'
|
||||
|
||||
# Call fastfetch with the temp file
|
||||
proc = subprocess.run([str(ff_path), '--raw' if legacy else '--file-raw',
|
||||
str(path.absolute()), *shlex.split(args)])
|
||||
|
||||
+14
-808
@@ -1,9 +1,10 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from typing import Iterable
|
||||
|
||||
from .color_util import RGB
|
||||
from .constants import GLOBAL_CFG
|
||||
from .constants import GLOBAL_CFG, SRC
|
||||
from .types import LightDark, ColorSpacing
|
||||
|
||||
|
||||
@@ -21,6 +22,16 @@ class ColorProfile:
|
||||
colors: list[RGB]
|
||||
spacing: ColorSpacing = 'equal'
|
||||
|
||||
@staticmethod
|
||||
def from_json(data: list | dict) -> 'ColorProfile':
|
||||
if isinstance(data, list):
|
||||
return ColorProfile(data)
|
||||
else:
|
||||
pf = ColorProfile(data['colors'])
|
||||
if 'weights' in data:
|
||||
pf = ColorProfile(pf.with_weights(data['weights']))
|
||||
return pf
|
||||
|
||||
def __init__(self, colors: list[str] | list[RGB]):
|
||||
if isinstance(colors[0], str):
|
||||
self.raw = colors
|
||||
@@ -165,811 +176,6 @@ class ColorProfile:
|
||||
|
||||
|
||||
PRESETS: dict[str, ColorProfile] = {
|
||||
'rainbow': ColorProfile([
|
||||
'#E50000',
|
||||
'#FF8D00',
|
||||
'#FFEE00',
|
||||
'#028121',
|
||||
'#004CFF',
|
||||
'#770088'
|
||||
]),
|
||||
|
||||
'transgender': ColorProfile([
|
||||
'#55CDFD',
|
||||
'#F6AAB7',
|
||||
'#FFFFFF',
|
||||
'#F6AAB7',
|
||||
'#55CDFD'
|
||||
]),
|
||||
|
||||
'nonbinary': ColorProfile([
|
||||
'#FCF431',
|
||||
'#FCFCFC',
|
||||
'#9D59D2',
|
||||
'#282828'
|
||||
]),
|
||||
|
||||
# xenogender sourced from https://commons.wikimedia.org/wiki/File:Xenogender_pride_flag.svg
|
||||
'xenogender': ColorProfile([
|
||||
'#FF6692',
|
||||
'#FF9A98',
|
||||
'#FFB883',
|
||||
'#FBFFA8',
|
||||
'#85BCFF',
|
||||
'#9D85FF',
|
||||
'#A510FF'
|
||||
]),
|
||||
|
||||
'agender': ColorProfile([
|
||||
'#000000',
|
||||
'#BABABA',
|
||||
'#FFFFFF',
|
||||
'#BAF484',
|
||||
'#FFFFFF',
|
||||
'#BABABA',
|
||||
'#000000'
|
||||
]),
|
||||
|
||||
'queer': ColorProfile([
|
||||
'#B57FDD',
|
||||
'#FFFFFF',
|
||||
'#49821E'
|
||||
]),
|
||||
|
||||
'genderfluid': ColorProfile([
|
||||
'#FE76A2',
|
||||
'#FFFFFF',
|
||||
'#BF12D7',
|
||||
'#000000',
|
||||
'#303CBE'
|
||||
]),
|
||||
|
||||
'bisexual': ColorProfile([
|
||||
'#D60270',
|
||||
'#9B4F96',
|
||||
'#0038A8'
|
||||
]),
|
||||
|
||||
'pansexual': ColorProfile([
|
||||
'#FF1C8D',
|
||||
'#FFD700',
|
||||
'#1AB3FF'
|
||||
]),
|
||||
|
||||
'polysexual': ColorProfile([
|
||||
'#F714BA',
|
||||
'#01D66A',
|
||||
'#1594F6',
|
||||
]),
|
||||
|
||||
# omnisexual sorced from https://www.flagcolorcodes.com/omnisexual
|
||||
'omnisexual': ColorProfile([
|
||||
'#FE9ACE',
|
||||
'#FF53BF',
|
||||
'#200044',
|
||||
'#6760FE',
|
||||
'#8EA6FF',
|
||||
]),
|
||||
|
||||
'omniromantic': ColorProfile([
|
||||
'#FEC8E4',
|
||||
'#FDA1DB',
|
||||
'#89739A',
|
||||
'#ABA7FE',
|
||||
'#BFCEFF',
|
||||
]),
|
||||
|
||||
# gay men sourced from https://www.flagcolorcodes.com/gay-men
|
||||
'gay-men': ColorProfile([
|
||||
'#078D70',
|
||||
'#98E8C1',
|
||||
'#FFFFFF',
|
||||
'#7BADE2',
|
||||
'#3D1A78'
|
||||
]),
|
||||
|
||||
'lesbian': ColorProfile([
|
||||
'#D62800',
|
||||
'#FF9B56',
|
||||
'#FFFFFF',
|
||||
'#D462A6',
|
||||
'#A40062'
|
||||
]),
|
||||
|
||||
# abrosexual used colorpicker to source from
|
||||
# https://fyeahaltpride.tumblr.com/post/151704251345/could-you-guys-possibly-make-an-abrosexual-pride
|
||||
'abrosexual': ColorProfile([
|
||||
'#46D294',
|
||||
'#A3E9CA',
|
||||
'#FFFFFF',
|
||||
'#F78BB3',
|
||||
'#EE1766',
|
||||
]),
|
||||
|
||||
'asexual': ColorProfile([
|
||||
'#000000',
|
||||
'#A4A4A4',
|
||||
'#FFFFFF',
|
||||
'#810081'
|
||||
]),
|
||||
|
||||
'aromantic': ColorProfile([
|
||||
'#3BA740',
|
||||
'#A8D47A',
|
||||
'#FFFFFF',
|
||||
'#ABABAB',
|
||||
'#000000'
|
||||
]),
|
||||
|
||||
# aroace1 sourced from https://flag.library.lgbt/flags/aroace/
|
||||
'aroace1': ColorProfile([
|
||||
'#E28C00',
|
||||
'#ECCD00',
|
||||
'#FFFFFF',
|
||||
'#62AEDC',
|
||||
'#203856'
|
||||
]),
|
||||
|
||||
'aroace2': ColorProfile([
|
||||
'#000000',
|
||||
'#810081',
|
||||
'#A4A4A4',
|
||||
'#FFFFFF',
|
||||
'#A8D47A',
|
||||
'#3BA740'
|
||||
]),
|
||||
|
||||
'aroace3': ColorProfile([
|
||||
'#3BA740',
|
||||
'#A8D47A',
|
||||
'#FFFFFF',
|
||||
'#ABABAB',
|
||||
'#000000',
|
||||
'#A4A4A4',
|
||||
'#FFFFFF',
|
||||
'#810081'
|
||||
]),
|
||||
|
||||
# below sourced from https://www.flagcolorcodes.com/flags/pride
|
||||
# goto f"https://www.flagcolorcodes.com/{preset}" for info
|
||||
# todo: sane sorting
|
||||
'autosexual': ColorProfile([
|
||||
'#99D9EA',
|
||||
'#7F7F7F'
|
||||
]),
|
||||
|
||||
'intergender': ColorProfile([
|
||||
# todo: use weighted spacing
|
||||
'#900DC2',
|
||||
'#900DC2',
|
||||
'#FFE54F',
|
||||
'#900DC2',
|
||||
'#900DC2',
|
||||
]),
|
||||
|
||||
'greygender': ColorProfile([
|
||||
'#B3B3B3',
|
||||
'#B3B3B3',
|
||||
'#FFFFFF',
|
||||
'#062383',
|
||||
'#062383',
|
||||
'#FFFFFF',
|
||||
'#535353',
|
||||
'#535353',
|
||||
]),
|
||||
|
||||
'akiosexual': ColorProfile([
|
||||
'#F9485E',
|
||||
'#FEA06A',
|
||||
'#FEF44C',
|
||||
'#FFFFFF',
|
||||
'#000000',
|
||||
]),
|
||||
|
||||
# bigender sourced from https://www.flagcolorcodes.com/bigender
|
||||
'bigender': ColorProfile([
|
||||
'#C479A2',
|
||||
'#EDA5CD',
|
||||
'#D6C7E8',
|
||||
'#FFFFFF',
|
||||
'#D6C7E8',
|
||||
'#9AC7E8',
|
||||
'#6D82D1',
|
||||
]),
|
||||
|
||||
# demigender yellow sourced from https://lgbtqia.fandom.com/f/p/4400000000000041031
|
||||
# other colors sourced from demiboy and demigirl flags
|
||||
'demigender': ColorProfile([
|
||||
'#7F7F7F',
|
||||
'#C4C4C4',
|
||||
'#FBFF75',
|
||||
'#FFFFFF',
|
||||
'#FBFF75',
|
||||
'#C4C4C4',
|
||||
'#7F7F7F',
|
||||
]),
|
||||
|
||||
# demiboy sourced from https://www.flagcolorcodes.com/demiboy
|
||||
'demiboy': ColorProfile([
|
||||
'#7F7F7F',
|
||||
'#C4C4C4',
|
||||
'#9DD7EA',
|
||||
'#FFFFFF',
|
||||
'#9DD7EA',
|
||||
'#C4C4C4',
|
||||
'#7F7F7F',
|
||||
]),
|
||||
|
||||
# demigirl sourced from https://www.flagcolorcodes.com/demigirl
|
||||
'demigirl': ColorProfile([
|
||||
'#7F7F7F',
|
||||
'#C4C4C4',
|
||||
'#FDADC8',
|
||||
'#FFFFFF',
|
||||
'#FDADC8',
|
||||
'#C4C4C4',
|
||||
'#7F7F7F',
|
||||
]),
|
||||
|
||||
'transmasculine': ColorProfile([
|
||||
'#FF8ABD',
|
||||
'#CDF5FE',
|
||||
'#9AEBFF',
|
||||
'#74DFFF',
|
||||
'#9AEBFF',
|
||||
'#CDF5FE',
|
||||
'#FF8ABD',
|
||||
]),
|
||||
|
||||
# transfeminine used colorpicker to source from https://www.deviantart.com/pride-flags/art/Trans-Woman-Transfeminine-1-543925985
|
||||
# linked from https://gender.fandom.com/wiki/Transfeminine
|
||||
'transfeminine': ColorProfile([
|
||||
'#73DEFF',
|
||||
'#FFE2EE',
|
||||
'#FFB5D6',
|
||||
'#FF8DC0',
|
||||
'#FFB5D6',
|
||||
'#FFE2EE',
|
||||
'#73DEFF',
|
||||
]),
|
||||
|
||||
# genderfaun sourced from https://www.flagcolorcodes.com/genderfaun
|
||||
'genderfaun': ColorProfile([
|
||||
'#FCD689',
|
||||
'#FFF09B',
|
||||
'#FAF9CD',
|
||||
'#FFFFFF',
|
||||
'#8EDED9',
|
||||
'#8CACDE',
|
||||
'#9782EC',
|
||||
]),
|
||||
|
||||
'demifaun': ColorProfile([
|
||||
'#7F7F7F',
|
||||
'#7F7F7F',
|
||||
'#C6C6C6',
|
||||
'#C6C6C6',
|
||||
'#FCC688',
|
||||
'#FFF19C',
|
||||
'#FFFFFF',
|
||||
'#8DE0D5',
|
||||
'#9682EC',
|
||||
'#C6C6C6',
|
||||
'#C6C6C6',
|
||||
'#7F7F7F',
|
||||
'#7F7F7F',
|
||||
]),
|
||||
|
||||
# genderfae sourced from https://www.flagcolorcodes.com/genderfae
|
||||
'genderfae': ColorProfile([
|
||||
'#97C3A5',
|
||||
'#C3DEAE',
|
||||
'#F9FACD',
|
||||
'#FFFFFF',
|
||||
'#FCA2C4',
|
||||
'#DB8AE4',
|
||||
'#A97EDD',
|
||||
]),
|
||||
|
||||
# demifae used colorpicker to source form https://www.deviantart.com/pride-flags/art/Demifae-870194777
|
||||
'demifae': ColorProfile([
|
||||
'#7F7F7F',
|
||||
'#7F7F7F',
|
||||
'#C5C5C5',
|
||||
'#C5C5C5',
|
||||
'#97C3A4',
|
||||
'#C4DEAE',
|
||||
'#FFFFFF',
|
||||
'#FCA2C5',
|
||||
'#AB7EDF',
|
||||
'#C5C5C5',
|
||||
'#C5C5C5',
|
||||
'#7F7F7F',
|
||||
'#7F7F7F',
|
||||
]),
|
||||
|
||||
'neutrois': ColorProfile([
|
||||
'#FFFFFF',
|
||||
'#1F9F00',
|
||||
'#000000'
|
||||
]),
|
||||
|
||||
'biromantic1': ColorProfile([
|
||||
'#8869A5',
|
||||
'#D8A7D8',
|
||||
'#FFFFFF',
|
||||
'#FDB18D',
|
||||
'#151638',
|
||||
]),
|
||||
|
||||
'biromantic2': ColorProfile([
|
||||
'#740194',
|
||||
'#AEB1AA',
|
||||
'#FFFFFF',
|
||||
'#AEB1AA',
|
||||
'#740194',
|
||||
]),
|
||||
|
||||
'autoromantic': ColorProfile([ # symbol interpreted
|
||||
'#99D9EA',
|
||||
'#99D9EA',
|
||||
'#3DA542',
|
||||
'#7F7F7F',
|
||||
'#7F7F7F',
|
||||
]),
|
||||
|
||||
# i didn't expect this one to work. cool!
|
||||
'boyflux2': ColorProfile(ColorProfile([
|
||||
'#E48AE4',
|
||||
'#9A81B4',
|
||||
'#55BFAB',
|
||||
'#FFFFFF',
|
||||
'#A8A8A8',
|
||||
'#81D5EF',
|
||||
'#69ABE5',
|
||||
'#5276D4',
|
||||
]).with_weights([1, 1, 1, 1, 1, 5, 5, 5])),
|
||||
|
||||
# sourced from https://commons.wikimedia.org/wiki/File:Girlflux_Pride_Flag.jpg
|
||||
"girlflux": ColorProfile([
|
||||
"f9e6d7",
|
||||
"f2526c",
|
||||
"bf0311",
|
||||
"e9c587",
|
||||
"bf0311",
|
||||
"f2526c",
|
||||
"f9e6d7",
|
||||
]),
|
||||
|
||||
# sourced from https://www.deviantart.com/pride-flags/art/Genderflux-1-543925589
|
||||
"genderflux": ColorProfile([
|
||||
"f47694",
|
||||
"f2a2b9",
|
||||
"cecece",
|
||||
"7ce0f7",
|
||||
"3ecdf9",
|
||||
"fff48d",
|
||||
]),
|
||||
|
||||
"finsexual": ColorProfile([
|
||||
"#B18EDF",
|
||||
"#D7B1E2",
|
||||
"#F7CDE9",
|
||||
"#F39FCE",
|
||||
"#EA7BB3",
|
||||
]),
|
||||
|
||||
'unlabeled1': ColorProfile([
|
||||
'#EAF8E4',
|
||||
'#FDFDFB',
|
||||
'#E1EFF7',
|
||||
'#F4E2C4'
|
||||
]),
|
||||
|
||||
'unlabeled2': ColorProfile([
|
||||
'#250548',
|
||||
'#FFFFFF',
|
||||
'#F7DCDA',
|
||||
'#EC9BEE',
|
||||
'#9541FA',
|
||||
'#7D2557'
|
||||
]),
|
||||
|
||||
'pangender': ColorProfile([
|
||||
'#FFF798',
|
||||
'#FEDDCD',
|
||||
'#FFEBFB',
|
||||
'#FFFFFF',
|
||||
'#FFEBFB',
|
||||
'#FEDDCD',
|
||||
'#FFF798',
|
||||
]),
|
||||
|
||||
'pangender.contrast': ColorProfile([
|
||||
'#ffe87f',
|
||||
'#fcbaa6',
|
||||
'#fbc9f3',
|
||||
'#FFFFFF',
|
||||
'#fbc9f3',
|
||||
'#fcbaa6',
|
||||
'#ffe87f',
|
||||
]),
|
||||
|
||||
'gendernonconforming1': ColorProfile(
|
||||
ColorProfile([
|
||||
'#50284d',
|
||||
'#96467b',
|
||||
'#5c96f7',
|
||||
'#ffe6f7',
|
||||
'#5c96f7',
|
||||
'#96467b',
|
||||
'#50284d'
|
||||
]).with_weights([
|
||||
4, 1, 1, 1, 1, 1, 4
|
||||
])
|
||||
),
|
||||
|
||||
'gendernonconforming2': ColorProfile([
|
||||
'#50284d',
|
||||
'#96467b',
|
||||
'#5c96f7',
|
||||
'#ffe6f7',
|
||||
'#5c96f7',
|
||||
'#96467b',
|
||||
'#50284d'
|
||||
]),
|
||||
|
||||
'femboy': ColorProfile([
|
||||
"#d260a5",
|
||||
"#e4afcd",
|
||||
"#fefefe",
|
||||
"#57cef8",
|
||||
"#fefefe",
|
||||
"#e4afcd",
|
||||
"#d260a5"
|
||||
]),
|
||||
|
||||
'tomboy': ColorProfile([
|
||||
"#2f3fb9",
|
||||
"#613a03",
|
||||
"#fefefe",
|
||||
"#f1a9b7",
|
||||
"#fefefe",
|
||||
"#613a03",
|
||||
"#2f3fb9"
|
||||
]),
|
||||
|
||||
'gynesexual': ColorProfile([
|
||||
"#F4A9B7",
|
||||
"#903F2B",
|
||||
"#5B953B",
|
||||
]),
|
||||
|
||||
'androsexual': ColorProfile([
|
||||
"#01CCFF",
|
||||
"#603524",
|
||||
"#B799DE",
|
||||
]),
|
||||
|
||||
# gendervoid and related flags sourced from: https://gender.fandom.com/wiki/Gendervoid
|
||||
'gendervoid': ColorProfile([
|
||||
"#081149",
|
||||
"#4B484B",
|
||||
"#000000",
|
||||
"#4B484B",
|
||||
"#081149"
|
||||
]),
|
||||
|
||||
'voidgirl': ColorProfile([
|
||||
"#180827",
|
||||
"#7A5A8B",
|
||||
"#E09BED",
|
||||
"#7A5A8B",
|
||||
"#180827"
|
||||
]),
|
||||
|
||||
'voidboy': ColorProfile([
|
||||
"#0B130C",
|
||||
"#547655",
|
||||
"#66B969",
|
||||
"#547655",
|
||||
"#0B130C"
|
||||
]),
|
||||
|
||||
# used https://twitter.com/foxbrained/status/1667621855518236674/photo/1 as source and colorpicked
|
||||
'nonhuman-unity': ColorProfile([
|
||||
"#177B49",
|
||||
"#FFFFFF",
|
||||
"#593C90"
|
||||
]),
|
||||
|
||||
# used https://pluralpedia.org/w/Plurality#/media/File:Plural-Flag-1.jpg as source and colorpicked
|
||||
'plural': ColorProfile([
|
||||
"#2D0625",
|
||||
"#543475",
|
||||
"#7675C3",
|
||||
"#89C7B0",
|
||||
"#F3EDBD",
|
||||
]),
|
||||
|
||||
# sampled from https://es.m.wikipedia.org/wiki/Archivo:Fraysexual_flag.jpg
|
||||
'fraysexual': ColorProfile([
|
||||
'#226CB5',
|
||||
'#94E7DD',
|
||||
'#FFFFFF',
|
||||
'#636363',
|
||||
]),
|
||||
|
||||
# Queer Subcultures
|
||||
# sourced from https://commons.wikimedia.org/wiki/File:Bear_Brotherhood_flag.svg
|
||||
'bear': ColorProfile([
|
||||
'#623804',
|
||||
'#D56300',
|
||||
'#FEDD63',
|
||||
'#FEE6B8',
|
||||
'#FFFFFF',
|
||||
'#555555',
|
||||
]),
|
||||
|
||||
# colorpicked from https://commons.wikimedia.org/wiki/File:Butch_Flag.png
|
||||
'butch': ColorProfile([
|
||||
'#D72800',
|
||||
'#F17623',
|
||||
'#FF9C56',
|
||||
'#FFFDF6',
|
||||
'#FFCE89',
|
||||
'#FEAF02',
|
||||
'#A37000',
|
||||
]),
|
||||
|
||||
# colorpicked from https://commons.wikimedia.org/wiki/File:Leather,_Latex,_and_BDSM_pride_-_Light.svg
|
||||
'leather': ColorProfile([
|
||||
'#000000',
|
||||
'#252580',
|
||||
'#000000',
|
||||
'#252580',
|
||||
'#FFFFFF',
|
||||
'#252580',
|
||||
'#000000',
|
||||
'#252580',
|
||||
'#000000',
|
||||
]),
|
||||
|
||||
# colorpicked from https://commons.wikimedia.org/wiki/File:Official_Otter_Pride_Flag_by_Bearbackgear.jpg
|
||||
'otter': ColorProfile([
|
||||
'#263881',
|
||||
'#5C9DC9',
|
||||
'#FFFFFF',
|
||||
'#3A291D',
|
||||
'#5C9DC9',
|
||||
'#263881',
|
||||
]),
|
||||
|
||||
# colorpicked from https://commons.wikimedia.org/wiki/File:Twink_Pride_Flag_(proposed).svg
|
||||
'twink': ColorProfile([
|
||||
'#FFB2FF',
|
||||
'#FFFFFF',
|
||||
'#FFFF81',
|
||||
]),
|
||||
|
||||
'kenochoric': ColorProfile([
|
||||
'#000000',
|
||||
'#2E1569',
|
||||
'#824DB7',
|
||||
'#C7A1D6',
|
||||
]),
|
||||
|
||||
'veldian': ColorProfile([
|
||||
'#D182A8',
|
||||
'#FAF6E0',
|
||||
'#69ACBE',
|
||||
'#5D448F',
|
||||
'#3A113E',
|
||||
]),
|
||||
|
||||
'solian': ColorProfile([
|
||||
'#FFF8ED',
|
||||
'#FFE7A8',
|
||||
'#F1B870',
|
||||
'#A56058',
|
||||
'#46281E',
|
||||
]),
|
||||
|
||||
'lunian': ColorProfile([
|
||||
'#2F0E62',
|
||||
'#6F41B1',
|
||||
'#889FDF',
|
||||
'#7DDFD5',
|
||||
'#D2F2E2',
|
||||
]),
|
||||
|
||||
# Start of Extras by Jaida Corvera
|
||||
# polyamorous flag colors pulled from https://polyamproud.com/flag
|
||||
'polyam': ColorProfile([
|
||||
"#FFFFFF",
|
||||
"#FCBF00",
|
||||
"#009FE3",
|
||||
"#E50051",
|
||||
"#340C46",
|
||||
]),
|
||||
|
||||
'sapphic': ColorProfile([
|
||||
"#FD8BA8",
|
||||
"#FBF2FF",
|
||||
"#C76BC5",
|
||||
"#FDD768",
|
||||
"#C76BC5",
|
||||
"#FBF2FF",
|
||||
"#FD8BA8"
|
||||
]),
|
||||
|
||||
'androgyne': ColorProfile([
|
||||
"#FE007F",
|
||||
"#9832FF",
|
||||
"#00B8E7",
|
||||
]),
|
||||
|
||||
'interprogress': ColorProfile([
|
||||
"#FFD800",
|
||||
"#7902AA",
|
||||
"#FFFFFF",
|
||||
"#FFAFC8",
|
||||
"#74D7EE",
|
||||
"#613915",
|
||||
"#000000",
|
||||
'#E50000',
|
||||
'#FF8D00',
|
||||
'#FFEE00',
|
||||
'#028121',
|
||||
'#004CFF',
|
||||
'#770088'
|
||||
]),
|
||||
|
||||
'progress': ColorProfile([
|
||||
"#FFFFFF",
|
||||
"#FFAFC8",
|
||||
"#74D7EE",
|
||||
"#613915",
|
||||
"#000000",
|
||||
'#E50000',
|
||||
'#FF8D00',
|
||||
'#FFEE00',
|
||||
'#028121',
|
||||
'#004CFF',
|
||||
'#770088'
|
||||
]),
|
||||
|
||||
'intersex': ColorProfile([
|
||||
"#FFD800",
|
||||
"#FFD800",
|
||||
"#7902AA",
|
||||
"#FFD800",
|
||||
"#FFD800"
|
||||
]),
|
||||
|
||||
'old-polyam': ColorProfile([
|
||||
"#0000FF",
|
||||
"#FF0000",
|
||||
"#FFFF00",
|
||||
"#FF0000",
|
||||
"#000000"
|
||||
]),
|
||||
|
||||
'equal-rights': ColorProfile([
|
||||
"#0000FF",
|
||||
"#0000FF",
|
||||
"#FFFF00",
|
||||
"#0000FF",
|
||||
"#0000FF",
|
||||
"#FFFF00",
|
||||
"#0000FF",
|
||||
"#0000FF"
|
||||
]),
|
||||
|
||||
'drag': ColorProfile([
|
||||
"#CC67FF",
|
||||
"#FFFFFF",
|
||||
"#FFA3E3",
|
||||
"#FFFFFF",
|
||||
"#3366FF"
|
||||
]),
|
||||
|
||||
# Pronoun Flags
|
||||
|
||||
'pronounfluid': ColorProfile([
|
||||
"#ffb3f9",
|
||||
"#ffffff",
|
||||
"#d1fdcb",
|
||||
"#c7b0ff",
|
||||
"#000000",
|
||||
"#b8ccff"
|
||||
]),
|
||||
|
||||
'pronounflux': ColorProfile([
|
||||
"#fdb3f8",
|
||||
"#b6ccfa",
|
||||
"#18ddd3",
|
||||
"#64ff89",
|
||||
"#ff7690",
|
||||
"#ffffff"
|
||||
]),
|
||||
|
||||
'exipronoun': ColorProfile([
|
||||
"#1c3d34",
|
||||
"#ffffff",
|
||||
"#321848",
|
||||
"#000000"
|
||||
]),
|
||||
|
||||
'neopronoun': ColorProfile([
|
||||
"#bcec64",
|
||||
"#ffffff",
|
||||
"#38077a"
|
||||
]),
|
||||
|
||||
'neofluid': ColorProfile([
|
||||
"#ffeca0",
|
||||
"#ffffff",
|
||||
"#ffeca0",
|
||||
"#38087a",
|
||||
"#bcec64"
|
||||
]),
|
||||
|
||||
'genderqueer': ColorProfile([
|
||||
"#b57edc",
|
||||
"#b57edc",
|
||||
"#ffffff",
|
||||
"#ffffff",
|
||||
"#4a8123",
|
||||
"#4a8123"
|
||||
]),
|
||||
|
||||
# Meme flags
|
||||
'beiyang': ColorProfile([
|
||||
'#DF1B12',
|
||||
'#FFC600',
|
||||
'#01639D',
|
||||
'#FFFFFF',
|
||||
'#000000',
|
||||
]),
|
||||
|
||||
'burger': ColorProfile([
|
||||
'#F3A26A',
|
||||
'#498701',
|
||||
'#FD1C13',
|
||||
'#7D3829',
|
||||
'#F3A26A',
|
||||
]),
|
||||
|
||||
'throatlozenges': ColorProfile([
|
||||
"#2759DA",
|
||||
"#03940D",
|
||||
"#F5F100",
|
||||
"#F59B00",
|
||||
"#B71212"
|
||||
]),
|
||||
|
||||
# colors from Gilbert Baker's original 1978 flag design
|
||||
# used https://gilbertbaker.com/rainbow-flag-color-meanings/ as source and colorpicked
|
||||
'baker': ColorProfile([
|
||||
'#F23D9E',
|
||||
'#F80A24',
|
||||
'#F78022',
|
||||
'#F9E81F',
|
||||
'#1E972E',
|
||||
'#1B86BC',
|
||||
'#243897',
|
||||
'#6F0A82',
|
||||
]),
|
||||
|
||||
# this is 4 all the dogs, from zombpawcoins on tumblr!
|
||||
'caninekin': ColorProfile([
|
||||
'#2d2822',
|
||||
'#543d25',
|
||||
'#9c754d',
|
||||
'#e8dac2',
|
||||
'#cfad8c',
|
||||
'#b77b55',
|
||||
'#954e31'
|
||||
])
|
||||
k: ColorProfile.from_json(v)
|
||||
for k, v in json.loads((SRC / 'data/presets.json').read_text('utf-8')).items()
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
from time import sleep
|
||||
|
||||
from hyfetch import presets
|
||||
from hyfetch.color_util import RGB, color, printc
|
||||
from hyfetch.constants import IS_WINDOWS
|
||||
from hyfetch.neofetch_util import term_size
|
||||
from hyfetch.presets import PRESETS
|
||||
from .color_util import RGB, color, printc
|
||||
from .constants import IS_WINDOWS
|
||||
from .neofetch_util import term_size
|
||||
from .presets import PRESETS
|
||||
|
||||
|
||||
def key_pressed():
|
||||
@@ -105,8 +106,8 @@ def start_animation():
|
||||
|
||||
try:
|
||||
while 1:
|
||||
# Clear the screen
|
||||
print("\033[2J\033[H", end="")
|
||||
# Move cursor to the top left corner
|
||||
print("\033[H", end="")
|
||||
draw_frame()
|
||||
frame += speed
|
||||
sleep(frame_delay)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from . import main
|
||||
from .color_util import printc
|
||||
|
||||
|
||||
def run_py():
|
||||
try:
|
||||
main.run()
|
||||
|
||||
+8
-4
@@ -1,18 +1,22 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from .color_util import printc
|
||||
from .constants import SRC
|
||||
from .py import run_py
|
||||
|
||||
|
||||
def run_rust():
|
||||
# Find the rust executable
|
||||
pd = Path(__file__).parent.joinpath('rust')
|
||||
pd = pd.joinpath('hyfetch.exe' if platform.system() == 'Windows' else 'hyfetch')
|
||||
pd = SRC / 'rust' / ('hyfetch.exe' if platform.system() == 'Windows' else 'hyfetch')
|
||||
if not pd.exists():
|
||||
printc('&cThe rust executable is not found, falling back to python...')
|
||||
if 'HYFETCH_DONT_WARN_RUST' not in os.environ:
|
||||
printc('&cThe executable for hyfetch v2 (rust) is not found, falling back to legacy v1.99.∞ (python).\n'
|
||||
'You can add environment variable HYFETCH_DONT_WARN_RUST=1 to suppress this warning.\n')
|
||||
run_py()
|
||||
return
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
version=7.98.0
|
||||
version=8.0.3
|
||||
|
||||
# Fallback to a value of '5' for shells which support bash
|
||||
# but do not set the 'BASH_' shell variables (osh).
|
||||
@@ -225,7 +225,7 @@ package_managers="on"
|
||||
|
||||
|
||||
# Show separate user and system packages for supported package managers
|
||||
#
|
||||
#
|
||||
# Default: 'on'
|
||||
# Values: 'on', 'off'
|
||||
# Flag: --package_separate
|
||||
@@ -868,7 +868,7 @@ image_source="auto"
|
||||
# NOTE: Adélie, aerOS, Afterglow, AIX, AlmaLinux, Alpine, Alter, Amazon, AmogOS, Anarchy, Android,
|
||||
# Antergos, antiX, AOSC OS, Aperio GNU/Linux, Aperture, Apricity, Arch, ArchBox, Archcraft,
|
||||
# archcraft_ascii, archcraft_minimal, ARCHlabs, ArchMerge, ArchStrike, ArcoLinux, Arkane, ArseLinux,
|
||||
# Artix, Arya, Asahi, AsteroidOS, astOS, Astra Linux, Athena, azos, Bedrock, BigLinux,
|
||||
# Artix, Arya, Asahi, AsteroidOS, astOS, Astra Linux, Athena, azos, Bazzite, Bedrock, BigLinux,
|
||||
# BigLinux_large, Bitrig, BlackArch, BlackMesa, blackPanther, BLAG, BlankOn, BlueLight, Bodhi,
|
||||
# bonsai, BSD, BunsenLabs, CachyOS, Calculate, CalinixOS, Carbs, CBL-Mariner, CelOS, Center, CentOS,
|
||||
# Chakra, ChaletOS, Chapeau, Chimera, ChonkySealOS, Chrom, Cleanjaro, Clear Linux OS, ClearOS,
|
||||
@@ -877,28 +877,29 @@ image_source="auto"
|
||||
# DracOS, DragonFly, Drauger, Droidian, Elementary, Elive, EncryptOS, EndeavourOS, Endless, Enso,
|
||||
# EuroLinux, EvolutionOS, eweOS, Exherbo, Exodia Predator OS, Fedora, Fedora Kinoite, Fedora
|
||||
# Sericea, Fedora Silverblue, Fedora_unicode, FemboyOS, Feren, Finnix, Floflis, FreeBSD, FreeMiNT,
|
||||
# Frugalware, Funtoo, Furreto, GalliumOS, Garuda, Gentoo, GhostBSD, glaucus, gNewSense, GNOME, GNU,
|
||||
# GoboLinux, GrapheneOS, Grombyang, Guix, Haiku, HamoniKR, HarDClanZ, Hash, Huayra, Hybrid, HydroOS,
|
||||
# Hyperbola, iglunix, instantOS, Interix, IRIX, Ironclad, Itc, januslinux, Kaisen, Kali, KaOS, KDE,
|
||||
# Kibojoe, Kogaion, Korora, KrassOS, KSLinux, Kubuntu, LainOS, LangitKetujuh, LaxerOS, LEDE,
|
||||
# LibreELEC, Linspire, Linux, Linux Lite, Linux Mint, Linux Mint Old, LinuxFromScratch, Live Raizo,
|
||||
# LMDE, Lubuntu, Lunar, mac, MacaroniOS, Mageia, Magix, MagpieOS, MainsailOS, Mandriva, Manjaro,
|
||||
# MassOS, MatuusOS, Maui, Mauna, Meowix, Mer, Minix, MIRACLE LINUX, MX, Namib, NekOS, Neptune,
|
||||
# NetBSD, Netrunner, Nitrux, NixOS, nixos_colorful, Nobara, NomadBSD, Nurunner, NuTyX, Obarun,
|
||||
# OBRevenge, OmniOS, Open Source Media Center, OpenBSD, openEuler, OpenIndiana, openKylin,
|
||||
# openmamba, OpenMandriva, OpenStage, openSUSE, openSUSE Leap, openSUSE Tumbleweed, OPNsense,
|
||||
# Oracle, orchid, OS Elbrus, PacBSD, Panwah, Parabola, parch, Pardus, Parrot, Parsix, PCBSD,
|
||||
# PCLinuxOS, pearOS, Pengwin, Pentoo, Peppermint, Peropesis, phyOS, PikaOS, Pisi, PNM Linux,
|
||||
# Pop!_OS, Porteus, PostMarketOS, Profelis SambaBOX, Proxmox, PuffOS, Puppy, PureOS, Q4OS, Qubes,
|
||||
# Qubyt, Quibian, Radix, Raspbian, ravynOS, Reborn OS, Red Star, Redcore, Redhat, Refracted Devuan,
|
||||
# Regata, Regolith, RhaymOS, rocky, Rosa, Sabayon, sabotage, Sailfish, SalentOS, Salient OS, Salix,
|
||||
# Sasanqua, Scientific, semc, Septor, Serene, SharkLinux, ShastraOS, Siduction, SkiffOS, Slackel,
|
||||
# Slackware, SliTaz, SmartOS, Soda, Solus, Source Mage, Sparky, Star, SteamOS, Stock Linux, Sulin,
|
||||
# SunOS, SwagArch, t2, Tails, Tatra, TeArch, TorizonCore, Trisquel, Twister, Ubuntu, Ubuntu Budgie,
|
||||
# Ubuntu Cinnamon, Ubuntu Kylin, Ubuntu MATE, Ubuntu Studio, Ubuntu Sway, Ubuntu Touch, Ubuntu-
|
||||
# GNOME, ubuntu_old02, Ultramarine Linux, unicodearch, Univalent, Univention, Uos, UrukOS, uwuntu,
|
||||
# Vanilla, Venom, VNux, Void, VzLinux, wii-linux-ngx, Windows, Windows 10, Windows 11, Windows95,
|
||||
# Wrt, Xenia, Xenia2, XFerience, Xray_OS, Xubuntu, yiffOS, Zorin have ascii logos.
|
||||
# Frugalware, Funtoo, Furreto, GalliumOS, Garuda, Gentoo, GhostBSD, glaucus, Gloire, gNewSense,
|
||||
# GNOME, GNU, GoboLinux, GrapheneOS, Grombyang, Guix, Haiku, HamoniKR, HarDClanZ, Hash, Huayra,
|
||||
# Hybrid, HydroOS, Hyperbola, iglunix, instantOS, Interix, IRIX, Itc, januslinux, Kaisen, Kali,
|
||||
# KaOS, KDE, Kibojoe, Kogaion, Korora, KrassOS, KSLinux, Kubuntu, LainOS, LangitKetujuh, LaxerOS,
|
||||
# LEDE, LibreELEC, Linspire, Linux, Linux Lite, Linux Mint, Linux Mint Old, LinuxFromScratch, Live
|
||||
# Raizo, LMDE, Lubuntu, Lunar, mac, MacaroniOS, Mageia, Magix, MagpieOS, MainsailOS, Mandriva,
|
||||
# Manjaro, MassOS, MatuusOS, Maui, Mauna, Meowix, Mer, Minix, MIRACLE LINUX, MX, Namib, NekOS,
|
||||
# Neptune, NetBSD, Netrunner, Nitrux, NixOS, nixos_colorful, Nobara, NomadBSD, Nurunner, NuTyX,
|
||||
# Obarun, OBRevenge, OmniOS, Open Source Media Center, OpenBSD, openEuler, OpenIndiana, openKylin,
|
||||
# openmamba, OpenMandriva, OpenStage, openSUSE, openSUSE Leap, openSUSE Tumbleweed, openSUSE
|
||||
# Tumbleweed-Slowroll, OPNsense, Oracle, orchid, OS Elbrus, PacBSD, Panwah, Parabola, parch, Pardus,
|
||||
# Parrot, Parsix, PCBSD, PCLinuxOS, pearOS, Pengwin, Pentoo, Peppermint, Peropesis, phyOS, PikaOS,
|
||||
# Pisi, PNM Linux, Pop!_OS, Porteus, PostMarketOS, Profelis SambaBOX, Proxmox, PuffOS, Puppy,
|
||||
# PureOS, Q4OS, Qubes, Qubyt, Quibian, Radix, Raspbian, ravynOS, Reborn OS, Red Star, Redcore,
|
||||
# Redhat, Refracted Devuan, Regata, Regolith, RhaymOS, Rhino Linux, rocky, Rosa, Sabayon, sabotage,
|
||||
# Sailfish, SalentOS, Salient OS, Salix, Sasanqua, Scientific, semc, Septor, Serene, SharkLinux,
|
||||
# ShastraOS, Siduction, SkiffOS, Slackel, Slackware, SliTaz, SmartOS, Soda, Solus, Source Mage,
|
||||
# Sparky, Star, SteamOS, Stock Linux, Sulin, SunOS, SwagArch, t2, Tails, Tatra, TeArch, TorizonCore,
|
||||
# Trisquel, Twister, Ubuntu, Ubuntu Budgie, Ubuntu Cinnamon, Ubuntu Kylin, Ubuntu MATE, Ubuntu
|
||||
# Studio, Ubuntu Sway, Ubuntu Touch, Ubuntu-GNOME, ubuntu_old02, Ultramarine Linux, unicodearch,
|
||||
# Univalent, Univention, Uos, UrukOS, uwuntu, Vanilla, Venom, VNux, Void, VzLinux, wii-linux-ngx,
|
||||
# Windows, Windows 10, Windows 11, Windows95, Wrt, Xenia, Xenia2, XFerience, Xray_OS, Xubuntu,
|
||||
# yiffOS, Zorin have ascii logos.
|
||||
|
||||
# NOTE: arch, dragonfly, Fedora, LangitKetujuh, nixos, redhat, Ubuntu have 'old' logo variants, use
|
||||
# {distro}_old to use them.
|
||||
@@ -1070,8 +1071,7 @@ get_distro() {
|
||||
[[ $distro ]] && return
|
||||
|
||||
case $os in
|
||||
Ironclad) distro=Ironclad ;;
|
||||
Linux|BSD|MINIX)
|
||||
Linux|BSD|MINIX|Ironclad)
|
||||
if [[ -f /bedrock/etc/bedrock-release && -z $BEDROCK_RESTRICT ]]; then
|
||||
case $distro_shorthand in
|
||||
on|tiny) distro="Bedrock Linux" ;;
|
||||
@@ -1145,7 +1145,7 @@ get_distro() {
|
||||
on|tiny) distro="LindowsOS" ;;
|
||||
*) distro="$(awk '/Version/ {print $2,$3}' /etc/lindowsos-version)"
|
||||
esac
|
||||
|
||||
|
||||
elif [[ -f /etc/astra_version ]]; then
|
||||
distro="Astra Linux"
|
||||
distro_version="$(sed -nr 's/^[^0-9]*(([0-9]+\.)*[0-9]+).*/\1/p' < /etc/astra_version)"
|
||||
@@ -1199,7 +1199,15 @@ get_distro() {
|
||||
elif type -p lsb_release >/dev/null; then
|
||||
# Debian does not include .x versions in /etc/os-version, but does in debian_version
|
||||
# So if that file exists, and we are not *buntu, build name from there
|
||||
if [[ -f /etc/debian_version ]] && [[ $(lsb_release -si) != *"buntu"* ]] && [[ $(lsb_release -si) != *"neon"* ]]; then
|
||||
if [[ $(lsb_release -si) = *"KSLinux"* ]]
|
||||
then
|
||||
. /etc/os-release
|
||||
case $distro_shorthand in
|
||||
on) distro=${NAME} ;;
|
||||
tiny) distro=${NAME} ;;
|
||||
*) distro="${NAME} ${VERSION}" ;;
|
||||
esac
|
||||
elif [[ -f /etc/debian_version ]] && [[ $(lsb_release -si) != *"buntu"* ]] && [[ $(lsb_release -si) != *"neon"* ]]; then
|
||||
. /etc/os-release
|
||||
case $distro_shorthand in
|
||||
on) distro="${NAME}" ;;
|
||||
@@ -1258,10 +1266,6 @@ get_distro() {
|
||||
elif type -p tazpkg >/dev/null; then
|
||||
distro="SliTaz $(< /etc/slitaz-release)"
|
||||
|
||||
elif type -p kpt >/dev/null && \
|
||||
type -p kpm >/dev/null; then
|
||||
distro=KSLinux
|
||||
|
||||
elif [[ -d /system/app/ && -d /system/priv-app ]]; then
|
||||
distro="Android $(getprop ro.build.version.release)"
|
||||
|
||||
@@ -1345,7 +1349,7 @@ get_distro() {
|
||||
windows_version_verbose=$(trim "${windows_version_verbose/REG_SZ}")
|
||||
buildnumber=$(reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -v CurrentBuildNumber | grep REG_)
|
||||
windows_version_verbose=$(trim "${windows_version_verbose/Windows}")
|
||||
windows_buildnumber=$(reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -v CurrentBuildNumber | grep REG_)
|
||||
windows_buildnumber=$(reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -v CurrentBuildNumber | grep REG_)
|
||||
windows_buildnumber=${buildnumber/CurrentBuildNumber}
|
||||
windows_buildnumber=${buildnumber/REG_SZ}
|
||||
if [[ "$windows_version_verbose" == *"10"* ]] && (( windows_buildnumber >= 22000 )); then
|
||||
@@ -1819,6 +1823,10 @@ get_model() {
|
||||
iPod5,1): "iPod touch 5G" ;;
|
||||
iPod7,1): "iPod touch 6G" ;;
|
||||
iPod9,1): "iPod touch 7G" ;;
|
||||
|
||||
AppleTV2,1): "Apple TV 2" ;;
|
||||
AppleTV3,1): "Apple TV 3" ;;
|
||||
AppleTV3,2): "Apple TV 3 (2013)" ;;
|
||||
esac
|
||||
|
||||
model=$_
|
||||
@@ -1932,7 +1940,7 @@ get_kernel() {
|
||||
*) kernel=${ver} ;;
|
||||
esac
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
# In Interix the Kernel version is commonly comprised of the host OS build number,
|
||||
# OS architecture and Interix build number
|
||||
@@ -1957,9 +1965,6 @@ get_kernel() {
|
||||
get_uptime() {
|
||||
# Get uptime in seconds.
|
||||
case $os in
|
||||
Ironclad)
|
||||
s=$(uptime -s)
|
||||
;;
|
||||
Linux|Windows|MINIX)
|
||||
if [[ -r /proc/uptime ]]; then
|
||||
s=$(< /proc/uptime)
|
||||
@@ -1988,7 +1993,7 @@ get_uptime() {
|
||||
s=$((now - boot))
|
||||
;;
|
||||
|
||||
AIX|IRIX)
|
||||
AIX|IRIX|Ironclad)
|
||||
t=$(LC_ALL=POSIX ps -o etime= -p 1)
|
||||
|
||||
[[ $t == *-* ]] && { d=${t%%-*}; t=${t#*-}; }
|
||||
@@ -2183,7 +2188,7 @@ get_packages() {
|
||||
has evox && tot cat /var/evox/packages/DB
|
||||
has squirrel && tot ls -w 1 /var/packages
|
||||
has anise && tot anise s --installed
|
||||
has am && pac "$(am -f --less)"
|
||||
has am && pac "$(am -f --less | awk '{ SUM += $1} END { print SUM }')"
|
||||
# Bonsai refers to the now archived repo https://github.com/mitchweaver/bonsai
|
||||
has bonsai && tot bonsai list
|
||||
# Rad refers to https://github.com/glaucuslinux/rad
|
||||
@@ -2192,7 +2197,7 @@ get_packages() {
|
||||
has radula && tot radula -cl
|
||||
# https://github.com/birb-linux/birb
|
||||
has birb && tot birb --list-installed
|
||||
|
||||
|
||||
has port && pkgs_h=1 tot port installed && ((packages-=1))
|
||||
|
||||
# Using the dnf package cache is much faster than rpm.
|
||||
@@ -2241,7 +2246,6 @@ get_packages() {
|
||||
fi
|
||||
|
||||
# Other (Needs complex command)
|
||||
has kpm-pkg && ((packages+=$(kpm --get-selections | grep -cv deinstall$)))
|
||||
|
||||
nix-user-pkgs() {
|
||||
if [ -d ~/.nix-profile ]; then
|
||||
@@ -2324,7 +2328,7 @@ get_packages() {
|
||||
has snap && ps -e | grep -qFm 1 snapd >/dev/null && \
|
||||
pkgs_h=1 tot snap list && ((packages-=1))
|
||||
|
||||
# Get AppImageLauncher Application directory,
|
||||
# Get AppImageLauncher Application directory,
|
||||
# See: https://github.com/TheAssassin/AppImageLauncher/wiki/Configuration#settings-file
|
||||
manager=appimage && has appimaged || [ -f "$HOME"/.config/appimagelauncher.cfg ] &&
|
||||
if [ -f "$HOME"/.config/appimagelauncher.cfg ]; then
|
||||
@@ -2336,7 +2340,7 @@ get_packages() {
|
||||
AIDIR="$HOME/.local/bin"
|
||||
fi &&
|
||||
dir "$AIDIR/*.[Aa]pp[Ii]mage \
|
||||
$ALDIR/*.[Aa]pp[Ii]mage"
|
||||
$ALDIR/*.[Aa]pp[Ii]mage"
|
||||
|
||||
# Has devbox & is initialized
|
||||
has devbox && [[ "$(devbox global list)" != *"not activated"* ]] && tot devbox global list
|
||||
@@ -2519,7 +2523,7 @@ get_editor() {
|
||||
esac
|
||||
editor_v="${editor_v/$'\n'*}"
|
||||
editor_v="${editor_v/Version: }"
|
||||
|
||||
|
||||
# Only show editor name if the version string doesn't contain it
|
||||
echo "$editor_v" | grep -i "$editor_name" &> /dev/null && editor_name=""
|
||||
editor=${editor_name}${editor_v:+ }${editor_v}
|
||||
@@ -2983,7 +2987,7 @@ get_wm_theme() {
|
||||
wm_theme=$(leftwm-theme status | grep "Your current theme" | sed -e 's/Your current theme is //g' -e 's/\,.*$//g')
|
||||
fi
|
||||
;;
|
||||
|
||||
|
||||
fly-wm)
|
||||
fly_config_file
|
||||
if grep -q 'DecorTheme' "${fly_config_file}" 2>/dev/null; then
|
||||
@@ -3175,19 +3179,10 @@ END
|
||||
;;
|
||||
|
||||
"Mac OS X"|"macOS")
|
||||
if [[ $osx_version == 10.[4-5]* ]]; then
|
||||
cpu="$(system_profiler SPHardwareDataType | grep CPU\ Type)"
|
||||
cpu="${cpu/CPU\ Type\:/}"
|
||||
|
||||
speed="$(system_profiler SPHardwareDataType | grep CPU\ Speed)"
|
||||
speed="${speed/CPU\ Speed\:/}"
|
||||
speed="${speed/ MHz/}"
|
||||
speed="${speed/ GHz/}"
|
||||
|
||||
cores="$(system_profiler SPHardwareDataType | grep Number\ Of\ CPUs)"
|
||||
cores="${cores/Number\ Of\ CPUs\:/}"
|
||||
else
|
||||
cpu="$(sysctl -n machdep.cpu.brand_string)"
|
||||
cpu="$(sysctl -n machdep.cpu.brand_string 2>/dev/null)"
|
||||
if [ -z "$cpu" ]; then
|
||||
cpu="$(system_profiler SPHardwareDataType | grep Processor\ Name)"
|
||||
cpu="${cpu/Processor\ Name\:/}"
|
||||
fi
|
||||
|
||||
# Get CPU cores.
|
||||
@@ -3241,6 +3236,10 @@ END
|
||||
"iPad7,"[1-4]): "Apple A10X Fusion (6) @ 2.39GHz" ;;
|
||||
"iPad8,"[1-8]): "Apple A12X Bionic (8) @ 2.49GHz" ;;
|
||||
"iPad8,9" | "iPad8,1"[0-2]): "Apple A12Z Bionic (8) @ 2.49GHz" ;;
|
||||
|
||||
"AppleTV2,1"): "Apple A4 (1) @ 1GHz" ;;
|
||||
"AppleTV3,1"): "Apple A5 (1) @ 1GHz" ;;
|
||||
"AppleTV3,2"): "Apple A5 (1) @ 1GHz" ;;
|
||||
esac
|
||||
cpu="$_"
|
||||
;;
|
||||
@@ -3374,7 +3373,6 @@ END
|
||||
cpu="${cpu//[1-9][0-9]-Core}"
|
||||
cpu="${cpu//[0-9]-Core}"
|
||||
cpu="${cpu//, * Compute Cores}"
|
||||
cpu="${cpu//Core / }"
|
||||
cpu="${cpu//(\"AuthenticAMD\"*)}"
|
||||
cpu="${cpu//with Radeon*Graphics}"
|
||||
cpu="${cpu//, altivec supported}"
|
||||
@@ -3547,10 +3545,12 @@ get_gpu() {
|
||||
"iPhone OS")
|
||||
case $kernel_machine in
|
||||
"iPhone1,"[1-2]): "PowerVR MBX Lite 3D" ;;
|
||||
"iPhone2,1" | "iPhone3,"[1-3] | "iPod3,1" | "iPod4,1" | "iPad1,"[1-2]):
|
||||
"iPhone2,1" | "iPhone3,"[1-3] | "iPod3,1" | "iPod4,1" | "iPad1,"[1-2] | "AppleTV2,1"):
|
||||
"PowerVR SGX535"
|
||||
;;
|
||||
"iPhone4,1" | "iPad2,"[1-7] | "iPod5,1"): "PowerVR SGX543MP2" ;;
|
||||
"iPhone4,1" | "iPad2,"[1-7] | "iPod5,1" | "AppleTV3,"[1-2]):
|
||||
"PowerVR SGX543MP2"
|
||||
;;
|
||||
"iPhone5,"[1-4]): "PowerVR SGX543MP3" ;;
|
||||
"iPhone6,"[1-2] | "iPad4,"[1-9]): "PowerVR G6430" ;;
|
||||
"iPhone7,"[1-2] | "iPod7,1" | "iPad5,"[1-2]): "PowerVR GX6450" ;;
|
||||
@@ -3663,13 +3663,19 @@ get_memory() {
|
||||
;;
|
||||
|
||||
"Mac OS X" | "macOS" | "iPhone OS")
|
||||
hw_pagesize="$(sysctl -n hw.pagesize)"
|
||||
mem_total="$(($(sysctl -n hw.memsize) / 1024))"
|
||||
pages_app="$(($(sysctl -n vm.page_pageable_internal_count) - $(sysctl -n vm.page_purgeable_count)))"
|
||||
pages_wired="$(vm_stat | awk '/ wired/ { print $4 }')"
|
||||
pages_compressed="$(vm_stat | awk '/ occupied/ { printf $5 }')"
|
||||
pages_compressed="${pages_compressed:-0}"
|
||||
mem_used="$(((pages_app + ${pages_wired//.} + ${pages_compressed//.}) * hw_pagesize / 1024))"
|
||||
pageable="$(sysctl -n vm.page_pageable_internal_count)"
|
||||
purgeable="$(sysctl -n vm.page_purgeable_count)"
|
||||
if [ -n "$pageable" ] && [ -n "$purgeable" ] && type -p vm_stat &>/dev/null; then
|
||||
hw_pagesize="$(sysctl -n hw.pagesize)"
|
||||
mem_total="$(($(sysctl -n hw.memsize) / 1024))"
|
||||
pages_app="$(($(sysctl -n vm.page_pageable_internal_count) - $(sysctl -n vm.page_purgeable_count)))"
|
||||
pages_wired="$(vm_stat | awk '/ wired/ { print $4 }')"
|
||||
pages_compressed="$(vm_stat | awk '/ occupied/ { printf $5 }')"
|
||||
pages_compressed="${pages_compressed:-0}"
|
||||
mem_used="$(((pages_app + ${pages_wired//.} + ${pages_compressed//.}) * hw_pagesize / 1024))"
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
;;
|
||||
|
||||
"BSD" | "MINIX" | "ravynOS")
|
||||
@@ -4171,6 +4177,7 @@ get_resolution() {
|
||||
"iPad13,"[1-2] | "iPad13,1"[6-9]): "1640x2360" ;;
|
||||
"iPad8,"[1-4] | "iPad8,"[9-10] | "iPad13,"[4-7] | "iPad14,"[3-6]): "1668x2388" ;;
|
||||
"iPad6,"[7-8] | "iPad7,"[1-2] | "iPad8,"[5-8] | "iPad8,1"[1-2] | "iPad13,"[8-9] | "iPad13,1"[0-1] | "iPad14,"[5-6]): "2048x2732" ;;
|
||||
"AppleTV"*) return ;;
|
||||
esac
|
||||
resolution="$_"
|
||||
;;
|
||||
@@ -4587,7 +4594,7 @@ get_python_ver() {
|
||||
if command -v python &> /dev/null; then
|
||||
python_ver=$(python -VVV)
|
||||
python_ver=${python_ver//$'\n'/}
|
||||
python_ver=${python_ver//\(+([^\)])\)}
|
||||
python_ver=${python_ver//+([[:space:]])\(+([^\)])\)}
|
||||
python_ver=$(echo "$python_ver" | awk '$1=$1')
|
||||
fi
|
||||
}
|
||||
@@ -5305,6 +5312,16 @@ get_local_ip() {
|
||||
}
|
||||
|
||||
get_public_ip() {
|
||||
if [[ -z "$public_ip_host" ]] && type -p dig >/dev/null; then
|
||||
public_ip="$(dig +time=1 +tries=1 +short TXT ch whoami.cloudflare @1.1.1.1 | tr -d '"')"
|
||||
[[ "$public_ip" =~ ^\; ]] && unset public_ip
|
||||
fi
|
||||
|
||||
if [[ -z "$public_ip_host" ]] && [[ -z "$public_ip" ]] && type -p drill >/dev/null; then
|
||||
public_ip="$(drill whoami.cloudflare TXT CH @1.1.1.1 | awk '/^whoami\./ && $3 == "CH" {print $5}' | tr -d '"')"
|
||||
fi
|
||||
|
||||
# Fallback
|
||||
if [[ -z "$public_ip_host" ]] && type -p dig >/dev/null; then
|
||||
public_ip="$(dig +time=1 +tries=1 +short myip.opendns.com @resolver1.opendns.com)"
|
||||
[[ "$public_ip" =~ ^\; ]] && unset public_ip
|
||||
@@ -6379,6 +6396,11 @@ cache_uname() {
|
||||
ProductVersion) osx_version=${sw_vers[i+1]} ;;
|
||||
ProductBuildVersion) osx_build=${sw_vers[i+1]} ;;
|
||||
esac
|
||||
# before iOS 2, iOS didn't internally distinguish between itself and macOS,
|
||||
# so we manually set the OS type if the version is 1.x
|
||||
case $osx_version in
|
||||
1.*) darwin_name="iPhone OS" ;;
|
||||
esac
|
||||
}
|
||||
fi
|
||||
}
|
||||
@@ -6620,12 +6642,12 @@ ASCII:
|
||||
GNU/Linux, Aperture, Apricity, Arch, ArchBox, Archcraft,
|
||||
archcraft_ascii, archcraft_minimal, ARCHlabs, ArchMerge, ArchStrike,
|
||||
ArcoLinux, Arkane, ArseLinux, Artix, Arya, Asahi, AsteroidOS, astOS,
|
||||
Astra Linux, Athena, azos, Bedrock, BigLinux, BigLinux_large,
|
||||
Bitrig, BlackArch, BlackMesa, blackPanther, BLAG, BlankOn,
|
||||
BlueLight, Bodhi, bonsai, BSD, BunsenLabs, CachyOS, Calculate,
|
||||
CalinixOS, Carbs, CBL-Mariner, CelOS, Center, CentOS, Chakra,
|
||||
ChaletOS, Chapeau, Chimera, ChonkySealOS, Chrom, Cleanjaro, Clear
|
||||
Linux OS, ClearOS, Clover, Cobalt, Condres, Container Linux by
|
||||
Astra Linux, Athena, azos, Bazzite, Bedrock, BigLinux,
|
||||
BigLinux_large, Bitrig, BlackArch, BlackMesa, blackPanther, BLAG,
|
||||
BlankOn, BlueLight, Bodhi, bonsai, BSD, BunsenLabs, CachyOS,
|
||||
Calculate, CalinixOS, Carbs, CBL-Mariner, CelOS, Center, CentOS,
|
||||
Chakra, ChaletOS, Chapeau, Chimera, ChonkySealOS, Chrom, Cleanjaro,
|
||||
Clear Linux OS, ClearOS, Clover, Cobalt, Condres, Container Linux by
|
||||
CoreOS, CRUX, Crystal Linux, Cucumber, CutefishOS, CuteOS, CyberOS,
|
||||
dahlia, DarkOs, Darwin, Debian, Deepin, DesaOS, Devuan, DietPi,
|
||||
digital UNIX, DracOS, DragonFly, Drauger, Droidian, Elementary,
|
||||
@@ -6634,37 +6656,37 @@ ASCII:
|
||||
Kinoite, Fedora Sericea, Fedora Silverblue, Fedora_unicode,
|
||||
FemboyOS, Feren, Finnix, Floflis, FreeBSD, FreeMiNT, Frugalware,
|
||||
Funtoo, Furreto, GalliumOS, Garuda, Gentoo, GhostBSD, glaucus,
|
||||
gNewSense, GNOME, GNU, GoboLinux, GrapheneOS, Grombyang, Guix,
|
||||
Haiku, HamoniKR, HarDClanZ, Hash, Huayra, Hybrid, HydroOS,
|
||||
Hyperbola, iglunix, instantOS, Interix, IRIX, Ironclad, Itc,
|
||||
januslinux, Kaisen, Kali, KaOS, KDE, Kibojoe, Kogaion, Korora,
|
||||
KrassOS, KSLinux, Kubuntu, LainOS, LangitKetujuh, LaxerOS, LEDE,
|
||||
LibreELEC, Linspire, Linux, Linux Lite, Linux Mint, Linux Mint Old,
|
||||
LinuxFromScratch, Live Raizo, LMDE, Lubuntu, Lunar, mac, MacaroniOS,
|
||||
Mageia, Magix, MagpieOS, MainsailOS, Mandriva, Manjaro, MassOS,
|
||||
MatuusOS, Maui, Mauna, Meowix, Mer, Minix, MIRACLE LINUX, MX, Namib,
|
||||
NekOS, Neptune, NetBSD, Netrunner, Nitrux, NixOS, nixos_colorful,
|
||||
Nobara, NomadBSD, Nurunner, NuTyX, Obarun, OBRevenge, OmniOS, Open
|
||||
Source Media Center, OpenBSD, openEuler, OpenIndiana, openKylin,
|
||||
openmamba, OpenMandriva, OpenStage, openSUSE, openSUSE Leap,
|
||||
openSUSE Tumbleweed, OPNsense, Oracle, orchid, OS Elbrus, PacBSD,
|
||||
Panwah, Parabola, parch, Pardus, Parrot, Parsix, PCBSD, PCLinuxOS,
|
||||
pearOS, Pengwin, Pentoo, Peppermint, Peropesis, phyOS, PikaOS, Pisi,
|
||||
PNM Linux, Pop!_OS, Porteus, PostMarketOS, Profelis SambaBOX,
|
||||
Proxmox, PuffOS, Puppy, PureOS, Q4OS, Qubes, Qubyt, Quibian, Radix,
|
||||
Raspbian, ravynOS, Reborn OS, Red Star, Redcore, Redhat, Refracted
|
||||
Devuan, Regata, Regolith, RhaymOS, rocky, Rosa, Sabayon, sabotage,
|
||||
Sailfish, SalentOS, Salient OS, Salix, Sasanqua, Scientific, semc,
|
||||
Septor, Serene, SharkLinux, ShastraOS, Siduction, SkiffOS, Slackel,
|
||||
Slackware, SliTaz, SmartOS, Soda, Solus, Source Mage, Sparky, Star,
|
||||
SteamOS, Stock Linux, Sulin, SunOS, SwagArch, t2, Tails, Tatra,
|
||||
TeArch, TorizonCore, Trisquel, Twister, Ubuntu, Ubuntu Budgie,
|
||||
Ubuntu Cinnamon, Ubuntu Kylin, Ubuntu MATE, Ubuntu Studio, Ubuntu
|
||||
Sway, Ubuntu Touch, Ubuntu-GNOME, ubuntu_old02, Ultramarine Linux,
|
||||
unicodearch, Univalent, Univention, Uos, UrukOS, uwuntu, Vanilla,
|
||||
Venom, VNux, Void, VzLinux, wii-linux-ngx, Windows, Windows 10,
|
||||
Windows 11, Windows95, Wrt, Xenia, Xenia2, XFerience, Xray_OS,
|
||||
Xubuntu, yiffOS, Zorin have ascii logos.
|
||||
Gloire, gNewSense, GNOME, GNU, GoboLinux, GrapheneOS, Grombyang,
|
||||
Guix, Haiku, HamoniKR, HarDClanZ, Hash, Huayra, Hybrid, HydroOS,
|
||||
Hyperbola, iglunix, instantOS, Interix, IRIX, Itc, januslinux,
|
||||
Kaisen, Kali, KaOS, KDE, Kibojoe, Kogaion, Korora, KrassOS, KSLinux,
|
||||
Kubuntu, LainOS, LangitKetujuh, LaxerOS, LEDE, LibreELEC, Linspire,
|
||||
Linux, Linux Lite, Linux Mint, Linux Mint Old, LinuxFromScratch,
|
||||
Live Raizo, LMDE, Lubuntu, Lunar, mac, MacaroniOS, Mageia, Magix,
|
||||
MagpieOS, MainsailOS, Mandriva, Manjaro, MassOS, MatuusOS, Maui,
|
||||
Mauna, Meowix, Mer, Minix, MIRACLE LINUX, MX, Namib, NekOS, Neptune,
|
||||
NetBSD, Netrunner, Nitrux, NixOS, nixos_colorful, Nobara, NomadBSD,
|
||||
Nurunner, NuTyX, Obarun, OBRevenge, OmniOS, Open Source Media
|
||||
Center, OpenBSD, openEuler, OpenIndiana, openKylin, openmamba,
|
||||
OpenMandriva, OpenStage, openSUSE, openSUSE Leap, openSUSE
|
||||
Tumbleweed, openSUSE Tumbleweed-Slowroll, OPNsense, Oracle, orchid,
|
||||
OS Elbrus, PacBSD, Panwah, Parabola, parch, Pardus, Parrot, Parsix,
|
||||
PCBSD, PCLinuxOS, pearOS, Pengwin, Pentoo, Peppermint, Peropesis,
|
||||
phyOS, PikaOS, Pisi, PNM Linux, Pop!_OS, Porteus, PostMarketOS,
|
||||
Profelis SambaBOX, Proxmox, PuffOS, Puppy, PureOS, Q4OS, Qubes,
|
||||
Qubyt, Quibian, Radix, Raspbian, ravynOS, Reborn OS, Red Star,
|
||||
Redcore, Redhat, Refracted Devuan, Regata, Regolith, RhaymOS, Rhino
|
||||
Linux, rocky, Rosa, Sabayon, sabotage, Sailfish, SalentOS, Salient
|
||||
OS, Salix, Sasanqua, Scientific, semc, Septor, Serene, SharkLinux,
|
||||
ShastraOS, Siduction, SkiffOS, Slackel, Slackware, SliTaz, SmartOS,
|
||||
Soda, Solus, Source Mage, Sparky, Star, SteamOS, Stock Linux, Sulin,
|
||||
SunOS, SwagArch, t2, Tails, Tatra, TeArch, TorizonCore, Trisquel,
|
||||
Twister, Ubuntu, Ubuntu Budgie, Ubuntu Cinnamon, Ubuntu Kylin,
|
||||
Ubuntu MATE, Ubuntu Studio, Ubuntu Sway, Ubuntu Touch, Ubuntu-GNOME,
|
||||
ubuntu_old02, Ultramarine Linux, unicodearch, Univalent, Univention,
|
||||
Uos, UrukOS, uwuntu, Vanilla, Venom, VNux, Void, VzLinux, wii-linux-
|
||||
ngx, Windows, Windows 10, Windows 11, Windows95, Wrt, Xenia, Xenia2,
|
||||
XFerience, Xray_OS, Xubuntu, yiffOS, Zorin have ascii logos.
|
||||
|
||||
NOTE: arch, dragonfly, Fedora, LangitKetujuh, nixos, redhat, Ubuntu
|
||||
have 'old' logo variants, use {distro}_old to use them.
|
||||
@@ -7434,7 +7456,7 @@ EOF
|
||||
;;
|
||||
|
||||
"ArseLinux"*)
|
||||
set_colors 4 7
|
||||
set_colors 4 7
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
${c1}
|
||||
⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
@@ -7966,7 +7988,7 @@ EOF
|
||||
"aerOS"*)
|
||||
set_colors fg 0 0 0
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
${c1}
|
||||
${c1}
|
||||
ooo OOO OOO ooo
|
||||
oOO OOo
|
||||
oOO OOo
|
||||
@@ -8186,23 +8208,23 @@ EOF
|
||||
"azos"*)
|
||||
set_colors 6 1
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
${c1} ////. ${c2} (((((
|
||||
${c1} //////// ${c2} @((((((((
|
||||
${c1} //////// ${c2} @((((((((
|
||||
${c1} //////// /////// ${c2} ((((((( @((((((((
|
||||
${c1} //////// ///////// ${c2} ((((((((( @((((((((
|
||||
${c1} //////// ///////// ${c2} ((((((((( @((((((((
|
||||
${c1} //////// ///////// ////// ${c2} (((((( ((((((((( @((((((((
|
||||
${c1} //////// ///////// //////// ${c2} (((((((( ((((((((( @((((((((
|
||||
${c1} //////// ///////// //////// ${c2} (((((((( ((((((((( @((((((((
|
||||
${c1} //////// ///////// //////// ${c2} ((((((( ((((((((( @((((((((
|
||||
${c1} //////// ///////// /// ${c2} ( ((((((((( @((((((((
|
||||
${c1} //////// ///////// ${c2} ((((((((( @((((((((
|
||||
${c1} //////// ///////// ${c2} &(((((((( @((((((((
|
||||
${c1} //////// ////// ${c2} @(((( @((((((((
|
||||
${c1} //////// ${c2} @((((((((
|
||||
${c1} //////// ${c2} @((((((((
|
||||
${c1} ///// ${c2} (((((
|
||||
${c1} ////. ${c2} (((((
|
||||
${c1} //////// ${c2} @((((((((
|
||||
${c1} //////// ${c2} @((((((((
|
||||
${c1} //////// /////// ${c2} ((((((( @((((((((
|
||||
${c1} //////// ///////// ${c2} ((((((((( @((((((((
|
||||
${c1} //////// ///////// ${c2} ((((((((( @((((((((
|
||||
${c1} //////// ///////// ////// ${c2} (((((( ((((((((( @((((((((
|
||||
${c1} //////// ///////// //////// ${c2} (((((((( ((((((((( @((((((((
|
||||
${c1} //////// ///////// //////// ${c2} (((((((( ((((((((( @((((((((
|
||||
${c1} //////// ///////// //////// ${c2} ((((((( ((((((((( @((((((((
|
||||
${c1} //////// ///////// /// ${c2} ( ((((((((( @((((((((
|
||||
${c1} //////// ///////// ${c2} ((((((((( @((((((((
|
||||
${c1} //////// ///////// ${c2} &(((((((( @((((((((
|
||||
${c1} //////// ////// ${c2} @(((( @((((((((
|
||||
${c1} //////// ${c2} @((((((((
|
||||
${c1} //////// ${c2} @((((((((
|
||||
${c1} ///// ${c2} (((((
|
||||
EOF
|
||||
;;
|
||||
|
||||
@@ -8229,6 +8251,31 @@ ${c1}--------------------------------------
|
||||
EOF
|
||||
;;
|
||||
|
||||
"Bazzite"*)
|
||||
set_colors 5 5
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
${c1} %%%%%%====%%%%%%%%%%
|
||||
%%%%%%%% %%%%%%%%%%%%%%
|
||||
%%%%%%%%% %%%%%%%%%%%%%%%%
|
||||
%%%%%%%%% %%%%%%%%%%%%%%%###
|
||||
%%%%%%%%% %%%%%%%%%%%%%######
|
||||
== =======######
|
||||
== =========#####
|
||||
%%%%%%%%% %%%%%%%####======#####
|
||||
%%%%%%%%% %%%%%#######=====#####
|
||||
%%%%%%%%% %%%#########=====#####
|
||||
%%%%%%%%% %%##########=====#####
|
||||
%%%%%%%%%====###########=====######
|
||||
%%%%%%%%====#########======######
|
||||
%%%%%%%=====#####========######
|
||||
%%%%###===============#######
|
||||
%#######==========#########
|
||||
#######################
|
||||
###################
|
||||
###########
|
||||
EOF
|
||||
;;
|
||||
|
||||
"BigLinux_large"*)
|
||||
set_colors 2 3 4 7
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
@@ -8336,7 +8383,7 @@ EOF
|
||||
"BlackMesa")
|
||||
set_colors 1
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
${c1}
|
||||
${c1}
|
||||
.-;+$XHHHHHHX$+;-.
|
||||
,;X@@X%/;=----=:/%X@@X/,
|
||||
=$@@%=. .=+H@X:
|
||||
@@ -8746,6 +8793,8 @@ ${c1} .
|
||||
EOF
|
||||
;;
|
||||
|
||||
|
||||
|
||||
"CelOS"*)
|
||||
set_colors 4 6 0 5
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
@@ -9252,16 +9301,16 @@ ${c2}
|
||||
${c3}MMM1ua${c2}
|
||||
${c1}MM${c2}EE ${c3} MMMMM1uazE${c2}
|
||||
${c1}MM ${c2}EEEE ${c3}M1MM1uazzEn ${c2}EEEE MME
|
||||
EEEEE ${c3}MMM uazEno ${c2}EEEE
|
||||
EEEEE ${c3}MMM uazEno ${c2}EEEE
|
||||
EEEEE${c1}MMMMMMEno~; ${c2}EE E${c2}
|
||||
EE ${c1}MMMMMMMM~;;E ${c2}MMMMM M ${c2}
|
||||
E ${c1}MMMMMMMMM ${c2} E E ${c2}
|
||||
${c1}MMMMMMMMMMM
|
||||
${c1}MMMMMMMMM ${c2}EE ${c1}
|
||||
MM1MMMM ${c2}EEE ${c1}
|
||||
MMMMM
|
||||
MMM
|
||||
M
|
||||
${c1}MMMMMMMMMMM
|
||||
${c1}MMMMMMMMM ${c2}EE ${c1}
|
||||
MM1MMMM ${c2}EEE ${c1}
|
||||
MMMMM
|
||||
MMM
|
||||
M
|
||||
EOF
|
||||
;;
|
||||
|
||||
@@ -9409,24 +9458,24 @@ EOF
|
||||
"openKylin"*)
|
||||
set_colors 2 7
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
${c1}
|
||||
/KKK]
|
||||
KKKKKKK` ]KKKK\
|
||||
KKKKK/ /KKKKKKKKK\
|
||||
KKKK/ ,KKKKKKKKKKKK^
|
||||
,]KKK =KKK` /KKKKKKOOOOOO`
|
||||
,KKKKKK =KK /` [\OOOOOOO\
|
||||
\KKKKK =K ,OOOOOOO`
|
||||
,KKKKK =^ \OOOOOO
|
||||
,KKKK ^ OOOOOO^
|
||||
*KKK^ =OOOOO^
|
||||
OOKK^ OOOOOO^
|
||||
\OOOK\ /OOOOOO`
|
||||
OOOOOO] ,OOOOOOO^
|
||||
,OOOOOOOO\] ,[OOOOOOOOO/
|
||||
\OOOOOOOOOOOOOOOOOOOOO`
|
||||
[OOOOOOOOOOOOOOOO/`
|
||||
,[OOOOOOOOO]
|
||||
${c1}
|
||||
/KKK]
|
||||
KKKKKKK` ]KKKK\
|
||||
KKKKK/ /KKKKKKKKK\
|
||||
KKKK/ ,KKKKKKKKKKKK^
|
||||
,]KKK =KKK` /KKKKKKOOOOOO`
|
||||
,KKKKKK =KK /` [\OOOOOOO\
|
||||
\KKKKK =K ,OOOOOOO`
|
||||
,KKKKK =^ \OOOOOO
|
||||
,KKKK ^ OOOOOO^
|
||||
*KKK^ =OOOOO^
|
||||
OOKK^ OOOOOO^
|
||||
\OOOK\ /OOOOOO`
|
||||
OOOOOO] ,OOOOOOO^
|
||||
,OOOOOOOO\] ,[OOOOOOOOO/
|
||||
\OOOOOOOOOOOOOOOOOOOOO`
|
||||
[OOOOOOOOOOOOOOOO/`
|
||||
,[OOOOOOOOO]
|
||||
EOF
|
||||
;;
|
||||
|
||||
@@ -9857,21 +9906,21 @@ EOF
|
||||
"eweOS"*)
|
||||
set_colors 7 11 9 8 1
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
${c2} #####%%%
|
||||
${c2} ##%%${c3}////${c2}%%%%%${c3}///
|
||||
${c2} #%%%%${c3}////((((////${c2}%
|
||||
${c1} *@@@@@@@${c3}/${c5},,,${c3}/////${c5},,,${c2}%${c1}@@@@@@@
|
||||
${c1} .@@@@@@@@@@@${c3}////////${c2}%%%${c1}@@@@@@@@@@@@
|
||||
${c1} @@@${c4}...${c1}@@@@@@${c3}////${c2}%%${c3}////${c1}@@@@@@@@@@@@@@@@
|
||||
${c2} #####%%%
|
||||
${c2} ##%%${c3}////${c2}%%%%%${c3}///
|
||||
${c2} #%%%%${c3}////((((////${c2}%
|
||||
${c1} *@@@@@@@${c3}/${c5},,,${c3}/////${c5},,,${c2}%${c1}@@@@@@@
|
||||
${c1} .@@@@@@@@@@@${c3}////////${c2}%%%${c1}@@@@@@@@@@@@
|
||||
${c1} @@@${c4}...${c1}@@@@@@${c3}////${c2}%%${c3}////${c1}@@@@@@@@@@@@@@@@
|
||||
${c1} @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
${c1} @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
${c1} @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
${c1} @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
${c1} @@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
${c1} @@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
${c1} @@@@@@@@@@@@@@@@@@@@@@@
|
||||
${c1} @@@@@@ @@@@@@
|
||||
${c1} @@@ @@@
|
||||
${c1} @@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
${c1} @@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
${c1} @@@@@@@@@@@@@@@@@@@@@@@
|
||||
${c1} @@@@@@ @@@@@@
|
||||
${c1} @@@ @@@
|
||||
EOF
|
||||
;;
|
||||
|
||||
@@ -10769,7 +10818,7 @@ ${c2}~!!7JY5PGGBBBBBBBBGGGGGGGBGGGGGP5YJ?7~~~
|
||||
EOF
|
||||
;;
|
||||
|
||||
"Ironclad"*)
|
||||
"Gloire"*)
|
||||
set_colors 5 7 0
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
${c3}
|
||||
@@ -12093,7 +12142,7 @@ EOF
|
||||
"nixos_small")
|
||||
set_colors 4 6
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
${c1} \\\\ \\\\ //
|
||||
${c1} \\\\ \\\\ //
|
||||
==\\\\__\\\\/ //
|
||||
// \\\\//
|
||||
==// //==
|
||||
@@ -13001,39 +13050,39 @@ EOF
|
||||
set_colors 11
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
${c1}
|
||||
'',,, ,,,d,
|
||||
',, ,,'
|
||||
', ,.
|
||||
., '
|
||||
. .
|
||||
' .
|
||||
.. oddddkdlc:;,.. ..
|
||||
. ............lllc, .
|
||||
. ....................: .
|
||||
. . ....................
|
||||
'. ..........'o........d0XX0.
|
||||
....lllllllcOOOcllllll............cxlxc...;okkkx.
|
||||
..................................';lc'...lo.
|
||||
.'''''''''''''.....................,;,.......
|
||||
',,,,,,,,,,,,,,,,''...............dkkkd......
|
||||
',,,,,,,,,,,,,,,,,,,'............;okkkd;....
|
||||
.,,,,,,,,,,,,,,,,,,,,,............;cll;.....
|
||||
,,,,,,,,,,,,,,,,,,,,'....................:d,
|
||||
,,,,,,,,,,,,,,,,,,,....................oxxx:
|
||||
.,,,,,,,,,,,,,,,,,'..................oxxxxx. .
|
||||
.,,,,,,,,,,,,,,'.......... ,oxxxxxxx .
|
||||
.;,,,,,,,,,,,,'.. 'cxxxxxxxxx,
|
||||
:dl:,'',,'.... .;lxxxxxxxxxd;
|
||||
,codol:;'. ...,;cldxxxxxxxxxoc.
|
||||
.:cxxxxxdlccccc:ccldxxxxxxxxxxxxxx::.
|
||||
.'::dxxxxxxxxxxxxxxxxxxxxxxxd::'.
|
||||
..,::cdxxxxxxxxxxxxxdc::,..
|
||||
...,;:::::::;,...
|
||||
|
||||
|
||||
'',,, ,,,d,
|
||||
',, ,,'
|
||||
', ,.
|
||||
., '
|
||||
. .
|
||||
' .
|
||||
.. oddddkdlc:;,.. ..
|
||||
. ............lllc, .
|
||||
. ....................: .
|
||||
. . ....................
|
||||
'. ..........'o........d0XX0.
|
||||
....lllllllcOOOcllllll............cxlxc...;okkkx.
|
||||
..................................';lc'...lo.
|
||||
.'''''''''''''.....................,;,.......
|
||||
',,,,,,,,,,,,,,,,''...............dkkkd......
|
||||
',,,,,,,,,,,,,,,,,,,'............;okkkd;....
|
||||
.,,,,,,,,,,,,,,,,,,,,,............;cll;.....
|
||||
,,,,,,,,,,,,,,,,,,,,'....................:d,
|
||||
,,,,,,,,,,,,,,,,,,,....................oxxx:
|
||||
.,,,,,,,,,,,,,,,,,'..................oxxxxx. .
|
||||
.,,,,,,,,,,,,,,'.......... ,oxxxxxxx .
|
||||
.;,,,,,,,,,,,,'.. 'cxxxxxxxxx,
|
||||
:dl:,'',,'.... .;lxxxxxxxxxd;
|
||||
,codol:;'. ...,;cldxxxxxxxxxoc.
|
||||
.:cxxxxxdlccccc:ccldxxxxxxxxxxxxxx::.
|
||||
.'::dxxxxxxxxxxxxxxxxxxxxxxxd::'.
|
||||
..,::cdxxxxxxxxxxxxxdc::,..
|
||||
...,;:::::::;,...
|
||||
|
||||
|
||||
EOF
|
||||
;;
|
||||
|
||||
|
||||
"phyOS"*)
|
||||
set_colors 33 33 7 1
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
@@ -13497,26 +13546,26 @@ EOF
|
||||
"Reborn OS"* | "Reborn"*)
|
||||
set_colors 0 4 6
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
${c1} .======================.
|
||||
${c1}.#${c2}#*********${c1}%%${c2}*********#${c1}%:
|
||||
${c1}:%${c2}#**********${c1}%%${c2}**********#${c1}%-
|
||||
${c1}-%${c2}************${c1}%%${c2}************${c1}%=
|
||||
${c1}+%${c2}******${c1}%%#####${c1}%%#####%%${c2}******${c1}%+
|
||||
${c1}*%%#${c2}****${c1}%#${c3}+=====${c1}%%${c3}=====+${c1}#%${c2}****${c1}#%%*
|
||||
${c1}*%${c2}*#${c1}#%%#%#${c3}====+++${c1}%%${c3}+++====${c1}#%#%%#${c2}#*${c1}##.
|
||||
${c1}.##${c2}*****${c1}#%%%#${c3}*++${c1}%######%${c3}*+*${c1}#%%%#${c2}*****${c1}#%.
|
||||
${c1}:%#${c2}*****${c1}#%${c3}*=+*${c1}#%%${c3}*++++++*${c1}%%#${c3}*+=*${c1}%#${c2}*****${c1}#%:
|
||||
${c1} .======================.
|
||||
${c1}.#${c2}#*********${c1}%%${c2}*********#${c1}%:
|
||||
${c1}:%${c2}#**********${c1}%%${c2}**********#${c1}%-
|
||||
${c1}-%${c2}************${c1}%%${c2}************${c1}%=
|
||||
${c1}+%${c2}******${c1}%%#####${c1}%%#####%%${c2}******${c1}%+
|
||||
${c1}*%%#${c2}****${c1}%#${c3}+=====${c1}%%${c3}=====+${c1}#%${c2}****${c1}#%%*
|
||||
${c1}*%${c2}*#${c1}#%%#%#${c3}====+++${c1}%%${c3}+++====${c1}#%#%%#${c2}#*${c1}##.
|
||||
${c1}.##${c2}*****${c1}#%%%#${c3}*++${c1}%######%${c3}*+*${c1}#%%%#${c2}*****${c1}#%.
|
||||
${c1}:%#${c2}*****${c1}#%${c3}*=+*${c1}#%%${c3}*++++++*${c1}%%#${c3}*+=*${c1}%#${c2}*****${c1}#%:
|
||||
${c1}-%#${c2}*****${c1}#%${c3}+====*${c1}%${c3}*++++++++*${c1}%#${c3}====+${c1}%#${c2}******${c1}%-
|
||||
${c1}-%#${c2}*****${c1}#%${c3}+====*${c1}%${c3}*++++++++*${c1}%#${c3}====+${c1}%#${c2}******${c1}%=
|
||||
${c1}:%#${c2}*****${c1}#%${c3}*=+*${c1}#%%${c3}*++++++*${c1}%%#${c3}*+=*${c1}%#${c2}*****${c1}#%-
|
||||
${c1}.##${c2}*****${c1}#%%%#${c3}*+*${c1}%######%${c3}*+*${c1}#%%%#${c2}*****${c1}#%:
|
||||
${c1}.##${c2}**${c1}#%%#%#${c3}====+++${c1}%%${c3}+++====${c1}#%#%%#${c2}#*${c1}##.
|
||||
${c1}*%%#${c2}****${c1}%#${c3}+=====${c1}%%${c3}=====+${c1}#%${c2}****${c1}#%%*
|
||||
${c1}+%${c2}******${c1}%%#####%%#####%%${c2}******${c1}%*
|
||||
${c1}-%${c2}************${c1}%%${c2}************${c1}%=
|
||||
${c1}:%${c2}#**********${c1}%%${c2}**********#${c1}%-
|
||||
${c1}:%${c2}#*********${c1}%%${c2}*********#${c1}%:
|
||||
${c1}.======================.
|
||||
${c1}:%#${c2}*****${c1}#%${c3}*=+*${c1}#%%${c3}*++++++*${c1}%%#${c3}*+=*${c1}%#${c2}*****${c1}#%-
|
||||
${c1}.##${c2}*****${c1}#%%%#${c3}*+*${c1}%######%${c3}*+*${c1}#%%%#${c2}*****${c1}#%:
|
||||
${c1}.##${c2}**${c1}#%%#%#${c3}====+++${c1}%%${c3}+++====${c1}#%#%%#${c2}#*${c1}##.
|
||||
${c1}*%%#${c2}****${c1}%#${c3}+=====${c1}%%${c3}=====+${c1}#%${c2}****${c1}#%%*
|
||||
${c1}+%${c2}******${c1}%%#####%%#####%%${c2}******${c1}%*
|
||||
${c1}-%${c2}************${c1}%%${c2}************${c1}%=
|
||||
${c1}:%${c2}#**********${c1}%%${c2}**********#${c1}%-
|
||||
${c1}:%${c2}#*********${c1}%%${c2}*********#${c1}%:
|
||||
${c1}.======================.
|
||||
EOF
|
||||
;;
|
||||
|
||||
@@ -13690,24 +13739,51 @@ EOF
|
||||
"RhaymOS"*)
|
||||
set_colors 1
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
${c1}
|
||||
###
|
||||
#####
|
||||
|
||||
####### /########
|
||||
############# ###########
|
||||
,########### #### ####(..
|
||||
#### #### ####* ##########
|
||||
${c1}
|
||||
###
|
||||
#####
|
||||
|
||||
####### /########
|
||||
############# ###########
|
||||
,########### #### ####(..
|
||||
#### #### ####* ##########
|
||||
#### ##### ##### (####
|
||||
#### ########### ###########
|
||||
#### ######### ##########
|
||||
|
||||
###################################
|
||||
#####################################
|
||||
#### ########### ###########
|
||||
#### ######### ##########
|
||||
|
||||
###################################
|
||||
#####################################
|
||||
#######################################
|
||||
EOF
|
||||
;;
|
||||
|
||||
"Rhino Linux"*)
|
||||
set_colors 5 4
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
${c1}
|
||||
${c1} ..','.. l.
|
||||
.,coooooooooc,..ool
|
||||
;oooooooooooooooooooo.,coo.
|
||||
;oooooooooooooooooooooooooo ,
|
||||
.ooooooooooooooooooooooooooo . ,o
|
||||
oollcccccccccllloooooooooooolcoo..oo
|
||||
ll;':::::::::::::::ccloooooooooooooo:
|
||||
.;''';::::::::::::::::::ccloooooooooo
|
||||
''''',:::::::::::::::::::::::cclllllc
|
||||
'''''';::::::::::::::::::::::::::::::
|
||||
${c1}.'''''';::::::::::::::::${c2}ll${c1}:::::::::::
|
||||
${c1} ''''''';:::::::::::::::${c2}d0${c1}::
|
||||
${c1}.''''''',;:::::::${c2}cc${c1}::::${c2}0N:'
|
||||
${c1}''''''''',,;::::${c2}cK${c1}:::${c2}dMX,
|
||||
${c1}'''''''''''',,,${c2}dMccOMM${c1}:
|
||||
${c1}.''''''''''''${c2}cWM0WMM${c1}.
|
||||
${c1}'''''''':${c2}kMMMMM${c1}.
|
||||
${c2}odxONMMMM
|
||||
;Kl
|
||||
EOF
|
||||
;;
|
||||
|
||||
|
||||
"rocky_small"*)
|
||||
set_colors 2
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
@@ -14986,29 +15062,29 @@ oss${c2}yNMMMNyMMh${c1}sssssssssssssshmmmh${c1}ssssssso
|
||||
.-\+oossssoo+/-.
|
||||
EOF
|
||||
;;
|
||||
|
||||
|
||||
"Floflis"*)
|
||||
set_colors 1 7 3
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
\e[96m ,▄▄▄▌▓▓███▓▓▌▄▄▄,
|
||||
,▄▒▓███████████████████▓▄▄
|
||||
▄▓███████████████████████████▌
|
||||
▓███████████████████████████████
|
||||
, ╙▓████████████████████████████▀ ▄
|
||||
╓█▓▄ ╙▀▓████████████████████▀▀` ,▄██▓
|
||||
╓█████▌▄, '▀▀▀▀▓▓▓▓▓▓▀▀Å╙` ▄▄▓█████▌
|
||||
\e[96m ,▄▄▄▌▓▓███▓▓▌▄▄▄,
|
||||
,▄▒▓███████████████████▓▄▄
|
||||
▄▓███████████████████████████▌
|
||||
▓███████████████████████████████
|
||||
, ╙▓████████████████████████████▀ ▄
|
||||
╓█▓▄ ╙▀▓████████████████████▀▀` ,▄██▓
|
||||
╓█████▌▄, '▀▀▀▀▓▓▓▓▓▓▀▀Å╙` ▄▄▓█████▌
|
||||
██████████▓▌▄ , ▄▓███████████▄
|
||||
╢████████████▓ ║████▓▓███▌ ╣█████████████▓
|
||||
▓█████████████ ▐█████████▀ ▓██████████████
|
||||
▓█████████████ ▐█████████▄ ███████████████
|
||||
▀████████████▌ ║█████████▌ ▀█████████████▌
|
||||
████████████M ▓██████████ ▐█████████████⌐
|
||||
▀██████████▌ ▐███████████▌ ▀███████████▌
|
||||
╙▓█████▓ ▓██████████████▄ ▀███████▀
|
||||
╝▓██▀ ╓▓████████████████▓ ▀▓██▀
|
||||
,▄████████████████████▌,
|
||||
╝▀████████████████████▓▀'
|
||||
`╙▀▀▓▓███████▓▀▀╩'
|
||||
▀██████████▌ ▐███████████▌ ▀███████████▌
|
||||
╙▓█████▓ ▓██████████████▄ ▀███████▀
|
||||
╝▓██▀ ╓▓████████████████▓ ▀▓██▀
|
||||
,▄████████████████████▌,
|
||||
╝▀████████████████████▓▀'
|
||||
`╙▀▀▓▓███████▓▀▀╩'
|
||||
EOF
|
||||
;;
|
||||
|
||||
@@ -15174,26 +15250,26 @@ EOF
|
||||
set_colors 12 12 7 12 4
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
${c3} :${c4}:::::::::::::: ${c5}.
|
||||
${c3}=#${c4}*============. ${c5}:#:
|
||||
${c3}=##%${c4}+----------. ${c5}.###:
|
||||
${c3}=####. ${c5}.####:
|
||||
${c3}=####. ${c5}.####:
|
||||
${c3}=###*. .=${c4}--------. ${c5}####:
|
||||
${c3}=####. .*#+${c4}======- ${c5}####:
|
||||
${c3}=###*. .*###+${c4}====- ${c5}####:
|
||||
${c3}=###*. .*#####+${c4}==- ${c5}####:
|
||||
${c3}=###*. .*#######+${c4}: ${c5}####:
|
||||
${c3}=###*. .*#######+${c4}: ${c5}####:
|
||||
${c3}=###*. .*#####+${c4}==- ${c5}####:
|
||||
${c3}=###*. .*###+${c4}====- ${c5}####:
|
||||
${c3}=####. .*#+${c4}======- ${c5}####:
|
||||
${c3}=###*. .=${c4}--------. ${c5}.####:
|
||||
${c3}=####. ${c5}.####:
|
||||
${c3}=####. ${c5}.####:
|
||||
${c3}=###+${c4}--------------${c5}####:
|
||||
${c3}=#+${c4}=================-${c5}:
|
||||
${c3}:${c4}::::::::::::::::::.
|
||||
|
||||
${c3}=#${c4}*============. ${c5}:#:
|
||||
${c3}=##%${c4}+----------. ${c5}.###:
|
||||
${c3}=####. ${c5}.####:
|
||||
${c3}=####. ${c5}.####:
|
||||
${c3}=###*. .=${c4}--------. ${c5}####:
|
||||
${c3}=####. .*#+${c4}======- ${c5}####:
|
||||
${c3}=###*. .*###+${c4}====- ${c5}####:
|
||||
${c3}=###*. .*#####+${c4}==- ${c5}####:
|
||||
${c3}=###*. .*#######+${c4}: ${c5}####:
|
||||
${c3}=###*. .*#######+${c4}: ${c5}####:
|
||||
${c3}=###*. .*#####+${c4}==- ${c5}####:
|
||||
${c3}=###*. .*###+${c4}====- ${c5}####:
|
||||
${c3}=####. .*#+${c4}======- ${c5}####:
|
||||
${c3}=###*. .=${c4}--------. ${c5}.####:
|
||||
${c3}=####. ${c5}.####:
|
||||
${c3}=####. ${c5}.####:
|
||||
${c3}=###+${c4}--------------${c5}####:
|
||||
${c3}=#+${c4}=================-${c5}:
|
||||
${c3}:${c4}::::::::::::::::::.
|
||||
|
||||
EOF
|
||||
;;
|
||||
|
||||
@@ -15219,25 +15295,25 @@ EOF
|
||||
set_colors 8 4
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
${c1}
|
||||
`-`
|
||||
-yys+/-`
|
||||
`oyyyyy: /osyyyyso+:.
|
||||
/yyyyy+`+yyyyyyyyyys/.
|
||||
.-yyyyys.:+//+oyyyyyyyo.
|
||||
`oy/`oyyyyy/ ./syyyyy:
|
||||
syyys`:yyyyyo` :yyyyy:
|
||||
/yyyyo .syyyyy- .yyyyy.
|
||||
yyyyy. +yyyyy/ /yyyy/
|
||||
`yyyyy :yyyyys` -yyyyo
|
||||
yyyyy. `syyyyy- /yyyy/
|
||||
/yyyyo /yyyyy+ .yyyyy.
|
||||
syyyys. -yyyyys.:yyyy:
|
||||
`oyyyyyo-` `oyyyyy:.sy:
|
||||
:syyyyyyso+/++`/yyyyyo``
|
||||
-oyyyyyyyyyyy-.syyyys.
|
||||
-/+osyyyyso.`+yyyyy/
|
||||
.-/+syo`
|
||||
`.
|
||||
`-`
|
||||
-yys+/-`
|
||||
`oyyyyy: /osyyyyso+:.
|
||||
/yyyyy+`+yyyyyyyyyys/.
|
||||
.-yyyyys.:+//+oyyyyyyyo.
|
||||
`oy/`oyyyyy/ ./syyyyy:
|
||||
syyys`:yyyyyo` :yyyyy:
|
||||
/yyyyo .syyyyy- .yyyyy.
|
||||
yyyyy. +yyyyy/ /yyyy/
|
||||
`yyyyy :yyyyys` -yyyyo
|
||||
yyyyy. `syyyyy- /yyyy/
|
||||
/yyyyo /yyyyy+ .yyyyy.
|
||||
syyyys. -yyyyys.:yyyy:
|
||||
`oyyyyyo-` `oyyyyy:.sy:
|
||||
:syyyyyyso+/++`/yyyyyo``
|
||||
-oyyyyyyyyyyy-.syyyys.
|
||||
-/+osyyyyso.`+yyyyy/
|
||||
.-/+syo`
|
||||
`.
|
||||
EOF
|
||||
;;
|
||||
|
||||
@@ -15738,21 +15814,21 @@ EOF
|
||||
set_colors 4 7
|
||||
read -rd '' ascii_data <<'EOF'
|
||||
${c1}
|
||||
. .:. . .:.
|
||||
.^^.!.:::. .^!?J?^
|
||||
.:^.^!!!~:~^. .7??77!~~^.
|
||||
.~^.!??77?!.^~: ..:^^7JJJ7~~^.
|
||||
.^~.^7???7~.~~. .7??????????!
|
||||
.:^:^^~^^:!^ ^: .......^!:...
|
||||
.!7~.::.!.::. ~BG~ :^ ^~:
|
||||
:!!~ ~. ?BBBB! ^?J!. .!~.
|
||||
:!. .JBY. .Y#BBBY?~!???J7. :^^.
|
||||
.. :5#B#P~P#BBP?7?55J?J7:
|
||||
^P#BBBBBBBB5?7J5555J!.....
|
||||
!BBBBBBGBBGJ77::Y555J?77777^
|
||||
?BBBBG5JJ5PJ?!: .?Y??????77?~.
|
||||
.YBGPYJ??????Y?^^^^~7?????????7?!.
|
||||
.^^:..::::::::.....:::::::::::..:.
|
||||
. .:. . .:.
|
||||
.^^.!.:::. .^!?J?^
|
||||
.:^.^!!!~:~^. .7??77!~~^.
|
||||
.~^.!??77?!.^~: ..:^^7JJJ7~~^.
|
||||
.^~.^7???7~.~~. .7??????????!
|
||||
.:^:^^~^^:!^ ^: .......^!:...
|
||||
.!7~.::.!.::. ~BG~ :^ ^~:
|
||||
:!!~ ~. ?BBBB! ^?J!. .!~.
|
||||
:!. .JBY. .Y#BBBY?~!???J7. :^^.
|
||||
.. :5#B#P~P#BBP?7?55J?J7:
|
||||
^P#BBBBBBBB5?7J5555J!.....
|
||||
!BBBBBBGBBGJ77::Y555J?77777^
|
||||
?BBBBG5JJ5PJ?!: .?Y??????77?~.
|
||||
.YBGPYJ??????Y?^^^^~7?????????7?!.
|
||||
.^^:..::::::::.....:::::::::::..:.
|
||||
EOF
|
||||
;;
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "neowofetch",
|
||||
"version": "1.99.0",
|
||||
"version": "2.0.3",
|
||||
"description": "Updated neofetch",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
# This script does some file path magic to make cargo publish work without having
|
||||
# to have neofetch & font logos in the cargo root.
|
||||
# ...okay basically it copies these files over before publishing.
|
||||
set -euo pipefail
|
||||
|
||||
# Get the directory of SRC root which is ../ from this script
|
||||
SRC_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
CARGO_ROOT="$SRC_ROOT/crates/hyfetch"
|
||||
|
||||
# Copy neofetch from here to cargo root
|
||||
cp "$SRC_ROOT/neofetch" "$CARGO_ROOT/"
|
||||
mkdir -p "$CARGO_ROOT/hyfetch"
|
||||
cp -r "$SRC_ROOT/hyfetch/data" "$CARGO_ROOT/hyfetch/"
|
||||
|
||||
# Build the crate
|
||||
cargo publish -p hyfetch --allow-dirty "$@"
|
||||
|
||||
# Delete the copied files
|
||||
rm "$CARGO_ROOT/neofetch"
|
||||
rm -rf "$CARGO_ROOT/hyfetch"
|
||||
|
||||
echo "Done!"
|
||||
+20
-4
@@ -51,8 +51,15 @@ def edit_versions(version: str):
|
||||
path = Path('hyfetch/__version__.py')
|
||||
content = [f"VERSION = '{version}'" if l.startswith('VERSION = ') else l for l in path.read_text().split('\n')]
|
||||
path.write_text('\n'.join(content))
|
||||
|
||||
# 3. Cargo.toml
|
||||
print('Editing Cargo.toml...')
|
||||
path = Path('Cargo.toml')
|
||||
content = path.read_text()
|
||||
content = re.sub(r'(?<=^version = ")[^"]+(?="$)', version, content, flags=re.MULTILINE)
|
||||
path.write_text(content)
|
||||
|
||||
# 3. README.md
|
||||
# 4. README.md
|
||||
print('Editing README.md...')
|
||||
path = Path('README.md')
|
||||
content = path.read_text()
|
||||
@@ -61,7 +68,7 @@ def edit_versions(version: str):
|
||||
content = content[:changelog_i] + f'\n\n### {version}' + content[changelog_i:]
|
||||
path.write_text(content)
|
||||
|
||||
# 4. neofetch script
|
||||
# 5. neofetch script
|
||||
print('Editing neofetch...')
|
||||
path = Path('neofetch')
|
||||
lines = path.read_text().replace("\t", " ").split('\n')
|
||||
@@ -93,7 +100,7 @@ def finalize_neofetch():
|
||||
# 2. Regenerate man page
|
||||
print('Regenerating neofetch man page...')
|
||||
Path('docs/neofetch.1').write_text(subprocess.check_output(['help2man', './neofetch']).decode())
|
||||
Path('docs/hyfetch.1').write_text(subprocess.check_output(['help2man', 'python3 -m hyfetch']).decode())
|
||||
Path('docs/hyfetch.1').write_text(subprocess.check_output(['help2man', 'cargo run --']).decode())
|
||||
|
||||
# 3. Reformat readme links
|
||||
print('Reformatting readme links...')
|
||||
@@ -125,7 +132,12 @@ def create_release(v: str):
|
||||
subprocess.check_call(['git', 'tag', f'neofetch-{NEOFETCH_NEW_VERSION}'])
|
||||
|
||||
i = input('Please check the commit is correct. Press y to continue or any other key to cancel.')
|
||||
assert i == 'y'
|
||||
if i.lower() != 'y':
|
||||
print('Aborting...')
|
||||
subprocess.check_call(['git', 'reset', '--hard', 'HEAD~1'])
|
||||
subprocess.check_call(['git', 'tag', '-d', v])
|
||||
subprocess.check_call(['git', 'tag', '-d', f'neofetch-{NEOFETCH_NEW_VERSION}'])
|
||||
exit(1)
|
||||
|
||||
# 4. Push
|
||||
print('Pushing commits...')
|
||||
@@ -140,6 +152,10 @@ def deploy():
|
||||
print('Deploying to pypi...')
|
||||
subprocess.check_call(['bash', 'tools/deploy.sh'])
|
||||
print('Done!')
|
||||
|
||||
print('Deploying to crates.io...')
|
||||
subprocess.check_call(['bash', 'tools/deploy-crate.sh'])
|
||||
print('Done!')
|
||||
|
||||
print('Deploying to npm...')
|
||||
otp = input('Please provide 2FA OTP for NPM: ')
|
||||
|
||||
Reference in New Issue
Block a user