forked from github-starred/hyprgui
add support for sourced files (#57)
* add functionality needed for sourced files to work * fix entry handling * run fmt * allow dead code * fix nested entries * fix nested option filling
This commit is contained in:
116
src/gui.rs
116
src/gui.rs
@@ -2834,17 +2834,113 @@ impl ConfigWidget {
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_value(&self, config: &HyprlandConfig, _category: &str, name: &str) -> String {
|
||||
let config_str = config.to_string();
|
||||
for line in config_str.lines() {
|
||||
if line.trim().starts_with(&format!("{} = ", name)) {
|
||||
return line
|
||||
.split('=')
|
||||
.nth(1)
|
||||
.map(|s| s.trim().to_string())
|
||||
.unwrap_or_default();
|
||||
fn extract_value(&self, config: &HyprlandConfig, category: &str, name: &str) -> String {
|
||||
let mut value = String::new();
|
||||
let parts: Vec<&str> = name.split(':').collect();
|
||||
|
||||
if parts.len() > 1 {
|
||||
if let Some(&(parent_start, parent_end)) = config.sections.get(category) {
|
||||
if parent_start < config.content.len() && parent_end < config.content.len() {
|
||||
let subsection = format!("{} {{", parts[0]);
|
||||
let mut in_subsection = false;
|
||||
|
||||
for line in &config.content[parent_start..=parent_end] {
|
||||
let trimmed = line.trim();
|
||||
|
||||
if trimmed == subsection {
|
||||
in_subsection = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if in_subsection {
|
||||
if trimmed == "}" {
|
||||
break;
|
||||
}
|
||||
|
||||
if trimmed.starts_with(parts[1])
|
||||
&& trimmed[parts[1].len()..].trim_start().starts_with('=')
|
||||
{
|
||||
if let Some(val) = trimmed.split('=').nth(1) {
|
||||
value = val.trim().to_string();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let Some(&(start, end)) = config.sections.get(category) {
|
||||
if start < config.content.len() && end < config.content.len() {
|
||||
for line in &config.content[start..=end] {
|
||||
let trimmed = line.trim();
|
||||
if trimmed.starts_with(name)
|
||||
&& trimmed[name.len()..].trim_start().starts_with('=')
|
||||
{
|
||||
if let Some(val) = line.split('=').nth(1) {
|
||||
value = val.trim().to_string();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
String::new()
|
||||
|
||||
if value.is_empty() {
|
||||
for idx in 0..config.sourced_content.len() {
|
||||
let section_key = format!("{}_{}", category, idx);
|
||||
if let Some(&(start, end)) = config.sourced_sections.get(§ion_key) {
|
||||
let sourced = &config.sourced_content[idx];
|
||||
if start < sourced.len() && end < sourced.len() {
|
||||
if parts.len() > 1 {
|
||||
let subsection = format!("{} {{", parts[0]);
|
||||
let mut in_subsection = false;
|
||||
|
||||
for line in &sourced[start..=end] {
|
||||
let trimmed = line.trim();
|
||||
|
||||
if trimmed == subsection {
|
||||
in_subsection = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if in_subsection {
|
||||
if trimmed == "}" {
|
||||
break;
|
||||
}
|
||||
|
||||
if trimmed.starts_with(parts[1])
|
||||
&& trimmed[parts[1].len()..].trim_start().starts_with('=')
|
||||
{
|
||||
if let Some(val) = trimmed.split('=').nth(1) {
|
||||
value = val.trim().to_string();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for line in &sourced[start..=end] {
|
||||
let trimmed = line.trim();
|
||||
if trimmed.starts_with(name)
|
||||
&& trimmed[name.len()..].trim_start().starts_with('=')
|
||||
{
|
||||
if let Some(val) = line.split('=').nth(1) {
|
||||
value = val.trim().to_string();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !value.is_empty() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
69
src/main.rs
69
src/main.rs
@@ -120,6 +120,26 @@ fn save_config_file(gui: Rc<RefCell<gui::ConfigGUI>>) {
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
for sourced_path in &parsed_config.sourced_paths {
|
||||
let sourced_backup = Path::new(sourced_path).with_file_name(format!(
|
||||
"{}{}",
|
||||
Path::new(sourced_path)
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap(),
|
||||
BACKUP_SUFFIX
|
||||
));
|
||||
if let Err(e) = fs::copy(sourced_path, &sourced_backup) {
|
||||
gui_ref.custom_error_popup(
|
||||
"Backup failed",
|
||||
&format!("Failed to create backup for sourced file: {}", e),
|
||||
true,
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gui_ref.apply_changes(&mut parsed_config);
|
||||
@@ -127,7 +147,7 @@ fn save_config_file(gui: Rc<RefCell<gui::ConfigGUI>>) {
|
||||
let updated_config_str = parsed_config.to_string();
|
||||
|
||||
match fs::write(&path, updated_config_str) {
|
||||
Ok(_) => println!("Configuration saved to: ~/{}", CONFIG_PATH),
|
||||
Ok(_) => println!("Configuration saved successfully"),
|
||||
Err(e) => {
|
||||
gui_ref.custom_error_popup(
|
||||
"Saving failed",
|
||||
@@ -151,13 +171,54 @@ fn undo_changes(gui: Rc<RefCell<gui::ConfigGUI>>) {
|
||||
));
|
||||
|
||||
if backup_path.exists() {
|
||||
let config_str = match fs::read_to_string(&path) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
gui_ref.custom_error_popup(
|
||||
"Reading failed",
|
||||
&format!("Failed to read configuration: {}", e),
|
||||
true,
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let parsed_config = parse_config(&config_str);
|
||||
|
||||
for sourced_path in &parsed_config.sourced_paths {
|
||||
let sourced_backup = Path::new(sourced_path).with_file_name(format!(
|
||||
"{}{}",
|
||||
Path::new(sourced_path)
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap(),
|
||||
BACKUP_SUFFIX
|
||||
));
|
||||
if sourced_backup.exists() {
|
||||
if let Err(e) = fs::copy(&sourced_backup, sourced_path) {
|
||||
gui_ref.custom_error_popup(
|
||||
"Undo Failed",
|
||||
&format!("Failed to restore sourced file from backup: {}", e),
|
||||
true,
|
||||
);
|
||||
return;
|
||||
}
|
||||
if let Err(e) = fs::remove_file(&sourced_backup) {
|
||||
gui_ref.custom_error_popup(
|
||||
"Backup Deletion Failed",
|
||||
&format!("Failed to delete sourced backup file: {}", e),
|
||||
true,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match fs::copy(&backup_path, &path) {
|
||||
Ok(_) => {
|
||||
println!("Configuration restored from backup");
|
||||
if let Ok(config_str) = fs::read_to_string(&path) {
|
||||
let parsed_config = parse_config(&config_str);
|
||||
gui_ref.load_config(&parsed_config);
|
||||
|
||||
gui_ref.get_changes().borrow_mut().clear();
|
||||
|
||||
if let Err(e) = fs::remove_file(&backup_path) {
|
||||
@@ -169,7 +230,7 @@ fn undo_changes(gui: Rc<RefCell<gui::ConfigGUI>>) {
|
||||
} else {
|
||||
gui_ref.custom_info_popup(
|
||||
"Undo Successful",
|
||||
"Configuration restored from backup and backup file deleted.",
|
||||
"Configuration restored from backup and backup files deleted.",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user