mirror of
https://github.com/hyprutils/hyprgui.git
synced 2026-07-19 04:00:30 -05:00
might be finished
This commit is contained in:
+69
-39
@@ -1,10 +1,9 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct HyprlandConfig {
|
||||
content: Vec<String>,
|
||||
sections: HashMap<String, usize>,
|
||||
added_entries: HashMap<String, HashSet<String>>,
|
||||
sections: HashMap<String, (usize, usize)>,
|
||||
}
|
||||
|
||||
impl HyprlandConfig {
|
||||
@@ -13,55 +12,86 @@ impl HyprlandConfig {
|
||||
}
|
||||
|
||||
pub fn parse(&mut self, config_str: &str) {
|
||||
let mut current_section = String::new();
|
||||
let mut section_start = 0;
|
||||
let mut section_stack = Vec::new();
|
||||
for (i, line) in config_str.lines().enumerate() {
|
||||
let trimmed = line.trim();
|
||||
if trimmed.ends_with('{') {
|
||||
current_section = trimmed.trim_end_matches('{').trim().to_string();
|
||||
section_start = i;
|
||||
} else if trimmed == "}" {
|
||||
if !current_section.is_empty() {
|
||||
self.sections.insert(current_section.clone(), section_start);
|
||||
current_section.clear();
|
||||
}
|
||||
let section_name = trimmed.trim_end_matches('{').trim().to_string();
|
||||
section_stack.push((section_name, i));
|
||||
} else if trimmed == "}" && !section_stack.is_empty() {
|
||||
let (name, start) = section_stack.pop().unwrap();
|
||||
let full_name = section_stack
|
||||
.iter()
|
||||
.map(|(n, _)| n.as_str())
|
||||
.chain(std::iter::once(name.as_str()))
|
||||
.collect::<Vec<_>>()
|
||||
.join(".");
|
||||
self.sections.insert(full_name, (start, i));
|
||||
}
|
||||
self.content.push(line.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_string(&self) -> String {
|
||||
let mut result = self.content.join("\n");
|
||||
for (category, entries) in &self.added_entries {
|
||||
for entry in entries {
|
||||
if !self.entry_exists(category, entry) {
|
||||
result.push_str(&format!("\n{}", entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn entry_exists(&self, category: &str, entry: &str) -> bool {
|
||||
self.content.iter().any(|line| line.trim() == entry)
|
||||
self.content.join("\n")
|
||||
}
|
||||
|
||||
pub fn add_entry(&mut self, category: &str, entry: &str) {
|
||||
if !self.entry_exists(category, entry) {
|
||||
if let Some(§ion_start) = self.sections.get(category) {
|
||||
let insert_position = self.content[section_start..]
|
||||
.iter()
|
||||
.position(|line| line.trim() == "}")
|
||||
.map(|pos| section_start + pos)
|
||||
.unwrap_or(self.content.len());
|
||||
self.content
|
||||
.insert(insert_position, format!(" {}", entry));
|
||||
} else {
|
||||
self.added_entries
|
||||
.entry(category.to_string())
|
||||
.or_insert_with(HashSet::new)
|
||||
.insert(entry.to_string());
|
||||
let parts: Vec<&str> = category.split('.').collect();
|
||||
let mut current_section = String::new();
|
||||
let mut depth = 0;
|
||||
|
||||
for (i, part) in parts.iter().enumerate() {
|
||||
if i > 0 {
|
||||
current_section.push('.');
|
||||
}
|
||||
current_section.push_str(part);
|
||||
|
||||
if let Some(&(start, end)) = self.sections.get(¤t_section) {
|
||||
if i == parts.len() - 1 {
|
||||
let key = entry.split('=').next().unwrap().trim();
|
||||
let existing_line = self.content[start..=end]
|
||||
.iter()
|
||||
.position(|line| line.trim().starts_with(key))
|
||||
.map(|pos| start + pos);
|
||||
|
||||
if let Some(line_num) = existing_line {
|
||||
self.content[line_num] = format!("{}{}", " ".repeat(depth + 1), entry);
|
||||
} else {
|
||||
self.content
|
||||
.insert(end, format!("{}{}", " ".repeat(depth + 1), entry));
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
let new_section = format!("{}{} {{", " ".repeat(depth), part);
|
||||
let insert_pos = if let Some(&(_, end)) = self.sections.get(&parts[..i].join(".")) {
|
||||
end + 1
|
||||
} else {
|
||||
self.content.len()
|
||||
};
|
||||
self.content.insert(insert_pos, new_section);
|
||||
self.content.insert(
|
||||
insert_pos + 1,
|
||||
format!("{}{}", " ".repeat(depth + 1), entry),
|
||||
);
|
||||
self.content
|
||||
.insert(insert_pos + 2, format!("{}}}", " ".repeat(depth)));
|
||||
|
||||
for (section, &mut (ref mut start, ref mut end)) in self.sections.iter_mut() {
|
||||
if *start >= insert_pos {
|
||||
*start += 3;
|
||||
*end += 3;
|
||||
} else if *end >= insert_pos {
|
||||
*end += 3;
|
||||
}
|
||||
}
|
||||
self.sections
|
||||
.insert(current_section.clone(), (insert_pos, insert_pos + 2));
|
||||
return;
|
||||
}
|
||||
|
||||
depth += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -10,10 +10,9 @@ fn main() {
|
||||
|
||||
let mut parsed_config = parse_config(&config_str);
|
||||
|
||||
parsed_config.add_entry("general", "new_option = value");
|
||||
parsed_config.add_entry("decoration", "rounding = 10");
|
||||
parsed_config.add_entry("decoration", "blur" "enabled = true");
|
||||
parsed_config.add_entry("decoration", "blur" "size = 10");
|
||||
parsed_config.add_entry("decoration.blur", "enabled = true");
|
||||
parsed_config.add_entry("decoration.blur", "size = 10");
|
||||
|
||||
let updated_config_str = parsed_config.to_string();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user