implement parsing ps dont mind the main changes thats for testing purposes

This commit is contained in:
nyx
2024-10-11 17:38:14 -04:00
parent d6c25f9da5
commit 07cb3c1930
5 changed files with 220 additions and 1 deletions

5
Cargo.lock generated
View File

@@ -386,11 +386,16 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hyprland-parser"
version = "0.1.0"
[[package]]
name = "hyprlandgui"
version = "0.1.0"
dependencies = [
"gtk4",
"hyprland-parser",
]
[[package]]

View File

@@ -16,4 +16,5 @@ categories = ["gui"]
edition = "2021"
[dependencies]
gtk = { version = "0.9.2", package = "gtk4", features = ["v4_16"] }
gtk = { version = "0.9.2", package = "gtk4", features = ["v4_16"] }
hyprland-parser = { path = "hyprland-parser" }

View File

@@ -0,0 +1,6 @@
[package]
name = "hyprland-parser"
version = "0.1.0"
edition = "2021"
[dependencies]

185
hyprland-parser/src/lib.rs Normal file
View File

@@ -0,0 +1,185 @@
use std::collections::HashMap;
#[derive(Debug, Default)]
pub struct HyprlandConfig {
general: HashMap<String, String>,
decoration: HashMap<String, String>,
animations: HashMap<String, String>,
input: HashMap<String, String>,
gestures: HashMap<String, String>,
group: HashMap<String, String>,
misc: HashMap<String, String>,
binds: HashMap<String, String>,
xwayland: HashMap<String, String>,
opengl: HashMap<String, String>,
render: HashMap<String, String>,
cursor: HashMap<String, String>,
debug: HashMap<String, String>,
blur: HashMap<String, String>,
touchpad: HashMap<String, String>,
touchdevice: HashMap<String, String>,
tablet: HashMap<String, String>,
groupbar: HashMap<String, String>,
exec: Vec<String>,
exec_once: Vec<String>,
monitor: Vec<String>,
windowrule: Vec<String>,
windowrulev2: Vec<String>,
bind: Vec<String>,
bindm: Vec<String>,
}
impl HyprlandConfig {
pub fn new() -> Self {
Self::default()
}
pub fn parse(&mut self, config_str: &str) {
let mut section_stack = Vec::new();
for line in config_str.lines() {
let trimmed = line.trim();
if trimmed.is_empty() || trimmed.starts_with('#') {
continue;
}
if trimmed.ends_with('{') {
let section = trimmed.trim_end_matches('{').trim().to_string();
section_stack.push(section);
continue;
}
if trimmed == "}" {
section_stack.pop();
continue;
}
if trimmed.starts_with("exec = ") {
self.exec.push(trimmed[6..].to_string());
} else if trimmed.starts_with("exec-once = ") {
self.exec_once.push(trimmed[11..].to_string());
} else if trimmed.starts_with("monitor = ") {
self.monitor.push(trimmed[9..].to_string());
} else if trimmed.starts_with("windowrule = ") {
self.windowrule.push(trimmed[12..].to_string());
} else if trimmed.starts_with("windowrulev2 = ") {
self.windowrulev2.push(trimmed[14..].to_string());
} else if trimmed.starts_with("bind = ") {
self.bind.push(trimmed[6..].to_string());
} else if trimmed.starts_with("bindm = ") {
self.bindm.push(trimmed[7..].to_string());
} else {
let parts: Vec<&str> = trimmed.splitn(2, '=').collect();
if parts.len() == 2 {
let key = parts[0].trim();
let value = parts[1].trim();
let current_section = section_stack.join(":");
match current_section.as_str() {
"general" => self.general.insert(key.to_string(), value.to_string()),
"decoration" => self.decoration.insert(key.to_string(), value.to_string()),
"animations" => self.animations.insert(key.to_string(), value.to_string()),
"input" => self.input.insert(key.to_string(), value.to_string()),
"gestures" => self.gestures.insert(key.to_string(), value.to_string()),
"group" => self.group.insert(key.to_string(), value.to_string()),
"misc" => self.misc.insert(key.to_string(), value.to_string()),
"binds" => self.binds.insert(key.to_string(), value.to_string()),
"xwayland" => self.xwayland.insert(key.to_string(), value.to_string()),
"opengl" => self.opengl.insert(key.to_string(), value.to_string()),
"render" => self.render.insert(key.to_string(), value.to_string()),
"cursor" => self.cursor.insert(key.to_string(), value.to_string()),
"debug" => self.debug.insert(key.to_string(), value.to_string()),
"decoration:blur" => self.blur.insert(key.to_string(), value.to_string()),
"input:touchpad" => {
self.touchpad.insert(key.to_string(), value.to_string())
}
"input:touchdevice" => {
self.touchdevice.insert(key.to_string(), value.to_string())
}
"input:tablet" => self.tablet.insert(key.to_string(), value.to_string()),
"group:groupbar" => {
self.groupbar.insert(key.to_string(), value.to_string())
}
_ => None,
};
}
}
}
}
pub fn to_string(&self) -> String {
let mut config = String::new();
for (key, value) in &self.general {
config.push_str(&format!("{} = {}\n", key, value));
}
let sections = [
("decoration", &self.decoration),
("animations", &self.animations),
("input", &self.input),
("gestures", &self.gestures),
("group", &self.group),
("misc", &self.misc),
("binds", &self.binds),
("xwayland", &self.xwayland),
("opengl", &self.opengl),
("render", &self.render),
("cursor", &self.cursor),
("debug", &self.debug),
];
for (section, map) in sections {
if !map.is_empty() {
config.push_str(&format!("\n{} {{\n", section));
for (key, value) in map {
config.push_str(&format!(" {} = {}\n", key, value));
}
config.push_str("}\n");
}
}
if !self.blur.is_empty() {
config.push_str("\ndecoration:blur {\n");
for (key, value) in &self.blur {
config.push_str(&format!(" {} = {}\n", key, value));
}
config.push_str("}\n");
}
let lists = [
("exec", &self.exec),
("exec-once", &self.exec_once),
("monitor", &self.monitor),
("windowrule", &self.windowrule),
("windowrulev2", &self.windowrulev2),
("bind", &self.bind),
("bindm", &self.bindm),
];
for (prefix, list) in lists {
for item in list {
config.push_str(&format!("{} = {}\n", prefix, item));
}
}
config
}
pub fn insert_general(&mut self, key: String, value: String) {
self.general.insert(key, value);
}
pub fn add_exec(&mut self, command: String) {
self.exec.push(command);
}
pub fn add_bind(&mut self, binding: String) {
self.bind.push(binding);
}
}
pub fn parse_config(config_str: &str) -> HyprlandConfig {
let mut config = HyprlandConfig::new();
config.parse(config_str);
config
}

View File

@@ -0,0 +1,22 @@
use hyprland_parser::parse_config;
use std::fs;
use std::path::PathBuf;
fn main() {
let home = std::env::var("HOME").unwrap();
let config_path = PathBuf::from(home).join(".config/hypr/hyprland.conf");
let config_str = fs::read_to_string(&config_path).unwrap();
let mut parsed_config = parse_config(&config_str);
parsed_config.insert_general("new_option".to_string(), "value".to_string());
parsed_config.add_exec("some_command --with-args".to_string());
parsed_config.add_bind("$mod, T, exec, kitty".to_string());
let updated_config_str = parsed_config.to_string();
fs::write(&config_path, updated_config_str).unwrap();
println!("Updated hyprland.conf with new configurations.");
}