You've already forked neo64fetch
mirror of
https://github.com/neoarz/neo64fetch.git
synced 2026-02-09 06:43:26 +01:00
feat: halfway there?
This commit is contained in:
50
src/helpers/cursor.rs
Normal file
50
src/helpers/cursor.rs
Normal file
@@ -0,0 +1,50 @@
|
||||
// https://github.com/fastfetch-cli/fastfetch/blob/dev/src/detection/cursor/cursor_apple.m
|
||||
|
||||
use plist::Value;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn format_color(dict: &plist::dictionary::Dictionary) -> String {
|
||||
let r = (dict.get("red").and_then(|v| v.as_real()).unwrap_or(0.0) * 255.0 + 0.5) as u32;
|
||||
let g = (dict.get("green").and_then(|v| v.as_real()).unwrap_or(0.0) * 255.0 + 0.5) as u32;
|
||||
let b = (dict.get("blue").and_then(|v| v.as_real()).unwrap_or(0.0) * 255.0 + 0.5) as u32;
|
||||
let a = (dict.get("alpha").and_then(|v| v.as_real()).unwrap_or(1.0) * 255.0 + 0.5) as u32;
|
||||
|
||||
let color_hex = (r << 24) | (g << 16) | (b << 8) | a;
|
||||
|
||||
match color_hex {
|
||||
0x000000FF => "Black".to_string(),
|
||||
0xFFFFFFFF => "White".to_string(),
|
||||
0xFF2600FF => "Red".to_string(),
|
||||
0x0433FFFF => "Blue".to_string(),
|
||||
0x00F900FF => "Green".to_string(),
|
||||
0xFFFB00FF => "Yellow".to_string(),
|
||||
_ => format!("#{:08X}", color_hex),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_cursor_info() -> String {
|
||||
let mut path = PathBuf::from(env::var("HOME").unwrap_or_default());
|
||||
path.push("Library/Preferences/com.apple.universalaccess.plist");
|
||||
|
||||
let mut fill = "Black".to_string();
|
||||
let mut outline = "White".to_string();
|
||||
let mut size = "32".to_string();
|
||||
|
||||
if let Ok(value) = Value::from_file(path) {
|
||||
if let Some(dict) = value.as_dictionary() {
|
||||
if let Some(f_dict) = dict.get("cursorFill").and_then(|v| v.as_dictionary()) {
|
||||
fill = format_color(f_dict);
|
||||
}
|
||||
if let Some(o_dict) = dict.get("cursorOutline").and_then(|v| v.as_dictionary()) {
|
||||
outline = format_color(o_dict);
|
||||
}
|
||||
|
||||
if let Some(s_val) = dict.get("mouseDriverCursorSize").and_then(|v| v.as_real()) {
|
||||
size = format!("{:.0}", s_val * 32.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
format!("Fill - {}, Outline - {} ({}px)", fill, outline, size)
|
||||
}
|
||||
22
src/helpers/desktop_env.rs
Normal file
22
src/helpers/desktop_env.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
// https://github.com/fastfetch-cli/fastfetch/blob/dev/src/detection/theme/theme_apple.c
|
||||
|
||||
use sysinfo::System;
|
||||
|
||||
pub fn get_desktop_env_info() -> String {
|
||||
let os_version = System::os_version().unwrap_or_else(|| "0.0.0".to_string());
|
||||
let major_version: u32 = os_version
|
||||
.split('.')
|
||||
.next()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.unwrap_or(0);
|
||||
|
||||
if major_version > 15 {
|
||||
"Liquid Glass".to_string()
|
||||
} else if major_version < 10 && major_version != 0 {
|
||||
"Platinum".to_string()
|
||||
} else if major_version >= 10 {
|
||||
"Aqua".to_string()
|
||||
} else {
|
||||
"Unknown".to_string()
|
||||
}
|
||||
}
|
||||
25
src/helpers/font.rs
Normal file
25
src/helpers/font.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
// https://github.com/fastfetch-cli/fastfetch/blob/dev/src/detection/font/font_apple.m
|
||||
|
||||
use objc2_app_kit::NSFont;
|
||||
use objc2_foundation::MainThreadMarker;
|
||||
|
||||
pub fn get_font_info() -> String {
|
||||
let _mtm = MainThreadMarker::new().expect("Must be on the main thread to query fonts");
|
||||
|
||||
let sys_font = NSFont::systemFontOfSize(12.0);
|
||||
let sys_name = sys_font
|
||||
.familyName()
|
||||
.expect("System font must have a family name")
|
||||
.to_string();
|
||||
|
||||
let user_font = NSFont::userFontOfSize(12.0);
|
||||
let user_name = match user_font {
|
||||
Some(font) => font
|
||||
.familyName()
|
||||
.map(|name| name.to_string())
|
||||
.unwrap_or_else(|| "Helvetica".to_string()),
|
||||
None => "Helvetica".to_string(),
|
||||
};
|
||||
|
||||
format!("{} [System], {} [User]", sys_name, user_name)
|
||||
}
|
||||
@@ -1,4 +1,11 @@
|
||||
pub mod cursor;
|
||||
pub mod desktop_env;
|
||||
pub mod display;
|
||||
pub mod font;
|
||||
pub mod packages;
|
||||
pub mod shell;
|
||||
pub mod terminal;
|
||||
pub mod terminal_font;
|
||||
pub mod uptime;
|
||||
pub mod wm;
|
||||
pub mod wm_theme;
|
||||
|
||||
38
src/helpers/terminal.rs
Normal file
38
src/helpers/terminal.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
use std::env;
|
||||
use sysinfo::System;
|
||||
|
||||
pub fn get_terminal_info() -> String {
|
||||
let term_env = env::var("TERM_PROGRAM")
|
||||
.or_else(|_| env::var("TERM"))
|
||||
.unwrap_or_default();
|
||||
|
||||
let term_ver = env::var("TERM_PROGRAM_VERSION").unwrap_or_default();
|
||||
|
||||
if !term_env.is_empty() && term_env != "xterm-256color" && term_env != "xterm" {
|
||||
let clean_name = term_env
|
||||
.replace("com.apple.", "") // Apple Terminal
|
||||
.replace("com.mitchellh.", "") // Ghostty
|
||||
.replace(".app", "");
|
||||
|
||||
return if term_ver.is_empty() {
|
||||
clean_name
|
||||
} else {
|
||||
format!("{} {}", clean_name, term_ver)
|
||||
};
|
||||
}
|
||||
|
||||
let mut sys = System::new();
|
||||
sys.refresh_processes(sysinfo::ProcessesToUpdate::All, true);
|
||||
|
||||
let my_pid = sysinfo::get_current_pid().unwrap_or(sysinfo::Pid::from(0));
|
||||
|
||||
if let Some(process) = sys.process(my_pid) {
|
||||
if let Some(parent_pid) = process.parent() {
|
||||
if let Some(parent_proc) = sys.process(parent_pid) {
|
||||
return parent_proc.name().to_string_lossy().replace(".app", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"unknown".to_string()
|
||||
}
|
||||
32
src/helpers/terminal_font.rs
Normal file
32
src/helpers/terminal_font.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
// https://github.com/fastfetch-cli/fastfetch/blob/dev/src/detection/terminalfont/terminalfont.c
|
||||
|
||||
use std::process::Command;
|
||||
|
||||
pub fn get_terminal_font_info() -> String {
|
||||
let output = Command::new("ghostty").arg("+show-config").output();
|
||||
|
||||
let mut font_family = String::new();
|
||||
let mut font_size = String::new();
|
||||
|
||||
if let Ok(out) = output {
|
||||
let stdout = String::from_utf8_lossy(&out.stdout);
|
||||
|
||||
for line in stdout.lines() {
|
||||
if line.starts_with("font-family =") && font_family.is_empty() {
|
||||
font_family = line.replace("font-family =", "").trim().to_string();
|
||||
}
|
||||
if line.starts_with("font-size =") && font_size.is_empty() {
|
||||
font_size = line.replace("font-size =", "").trim().to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if font_family.is_empty() {
|
||||
font_family = "JetBrainsMono Nerd Font".to_string();
|
||||
}
|
||||
if font_size.is_empty() {
|
||||
font_size = "13".to_string();
|
||||
}
|
||||
|
||||
format!("{} Regular ({}pt)", font_family, font_size)
|
||||
}
|
||||
47
src/helpers/wm.rs
Normal file
47
src/helpers/wm.rs
Normal file
@@ -0,0 +1,47 @@
|
||||
// https://github.com/fastfetch-cli/fastfetch/blob/dev/src/detection/displayserver/displayserver_apple.c
|
||||
|
||||
use plist::Value;
|
||||
use std::path::Path;
|
||||
|
||||
pub struct DisplayServerResult {
|
||||
pub wm_pretty_name: String,
|
||||
}
|
||||
|
||||
pub fn get_window_manager_info() -> DisplayServerResult {
|
||||
let mut result = DisplayServerResult {
|
||||
wm_pretty_name: "Quartz Compositor".to_string(),
|
||||
};
|
||||
|
||||
if cfg!(target_os = "macos") {
|
||||
let plist_path = "/System/Library/CoreServices/WindowManager.app/Contents/version.plist";
|
||||
|
||||
if Path::new(plist_path).exists() {
|
||||
if let Ok(value) = Value::from_file(plist_path) {
|
||||
if let Some(dict) = value.as_dictionary() {
|
||||
if let Some(raw_version) = dict.get("SourceVersion").and_then(|v| v.as_string())
|
||||
{
|
||||
// Apple format: AAAABBBCCDDDDDD (Major, Minor, Patch, Build)
|
||||
if raw_version.len() >= 8 && raw_version.chars().all(|c| c.is_numeric()) {
|
||||
let major =
|
||||
raw_version[..raw_version.len() - 12].trim_start_matches('0');
|
||||
let minor = raw_version[raw_version.len() - 12..raw_version.len() - 9]
|
||||
.trim_start_matches('0');
|
||||
let patch = raw_version[raw_version.len() - 9..raw_version.len() - 7]
|
||||
.trim_start_matches('0');
|
||||
|
||||
let m = if minor.is_empty() { "0" } else { minor };
|
||||
let p = if patch.is_empty() { "0" } else { patch };
|
||||
|
||||
result.wm_pretty_name =
|
||||
format!("Quartz Compositor {}.{}.{}", major, m, p);
|
||||
} else {
|
||||
result.wm_pretty_name = format!("Quartz Compositor {}", raw_version);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
40
src/helpers/wm_theme.rs
Normal file
40
src/helpers/wm_theme.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
// https://github.com/fastfetch-cli/fastfetch/blob/dev/src/detection/wmtheme/wmtheme_apple.m
|
||||
|
||||
use plist::Value;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn get_wm_theme_info() -> String {
|
||||
let mut path = PathBuf::from(env::var("HOME").unwrap_or_else(|_| "".to_string()));
|
||||
path.push("Library/Preferences/.GlobalPreferences.plist");
|
||||
|
||||
let mut accent_name = "Multicolor".to_string();
|
||||
let mut appearance = "Light".to_string();
|
||||
|
||||
if let Ok(value) = Value::from_file(path) {
|
||||
if let Some(dict) = value.as_dictionary() {
|
||||
if let Some(accent_val) = dict
|
||||
.get("AppleAccentColor")
|
||||
.and_then(|v| v.as_signed_integer())
|
||||
{
|
||||
accent_name = match accent_val {
|
||||
-1 => "Graphite".to_string(),
|
||||
0 => "Red".to_string(),
|
||||
1 => "Orange".to_string(),
|
||||
2 => "Yellow".to_string(),
|
||||
3 => "Green".to_string(),
|
||||
4 => "Blue".to_string(),
|
||||
5 => "Purple".to_string(),
|
||||
6 => "Pink".to_string(),
|
||||
_ => "Multicolor".to_string(),
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(style) = dict.get("AppleInterfaceStyle").and_then(|v| v.as_string()) {
|
||||
appearance = style.to_string(); // Usually "Dark"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
format!("{} ({})", accent_name, appearance)
|
||||
}
|
||||
25
src/main.rs
25
src/main.rs
@@ -2,7 +2,6 @@
|
||||
// neo64fetch - "jarvis, rewrite this project in rust"
|
||||
|
||||
// use colored::*;
|
||||
use display_info::DisplayInfo;
|
||||
use std::env;
|
||||
use sysinfo::System;
|
||||
mod helpers;
|
||||
@@ -19,8 +18,15 @@ struct Stats {
|
||||
packages: String,
|
||||
shell: String,
|
||||
display: String,
|
||||
desktop_env: String,
|
||||
window_manager: String,
|
||||
window_manager_theme: String,
|
||||
font: String,
|
||||
cursor: String,
|
||||
terminal: String,
|
||||
terminal_font: String,
|
||||
|
||||
// Extra fields which are usually appended
|
||||
// Extra fields
|
||||
architecture: String,
|
||||
}
|
||||
|
||||
@@ -41,8 +47,16 @@ fn main() {
|
||||
packages: helpers::packages::get_brew_info(),
|
||||
shell: helpers::shell::get_shell_info(),
|
||||
display: helpers::display::get_display_info(),
|
||||
desktop_env: helpers::desktop_env::get_desktop_env_info(),
|
||||
window_manager: helpers::wm::get_window_manager_info().wm_pretty_name,
|
||||
window_manager_theme: helpers::wm_theme::get_wm_theme_info(),
|
||||
font: helpers::font::get_font_info(),
|
||||
cursor: helpers::cursor::get_cursor_info(),
|
||||
terminal: helpers::terminal::get_terminal_info(),
|
||||
terminal_font: helpers::terminal_font::get_terminal_font_info(),
|
||||
};
|
||||
|
||||
// TODO: Add ascii art support later
|
||||
// Testing each component separately; going to comment out at the end
|
||||
{
|
||||
println!("{}", stats.username);
|
||||
@@ -55,5 +69,12 @@ fn main() {
|
||||
println!("{}", stats.packages);
|
||||
println!("{}", stats.shell);
|
||||
println!("{}", stats.display);
|
||||
println!("{}", stats.desktop_env);
|
||||
println!("{}", stats.window_manager);
|
||||
println!("{}", stats.window_manager_theme);
|
||||
println!("{}", stats.font);
|
||||
println!("{}", stats.cursor);
|
||||
println!("{}", stats.terminal);
|
||||
println!("{}", stats.terminal_font);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user