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 {
|
fn extract_value(&self, config: &HyprlandConfig, category: &str, name: &str) -> String {
|
||||||
let config_str = config.to_string();
|
let mut value = String::new();
|
||||||
for line in config_str.lines() {
|
let parts: Vec<&str> = name.split(':').collect();
|
||||||
if line.trim().starts_with(&format!("{} = ", name)) {
|
|
||||||
return line
|
if parts.len() > 1 {
|
||||||
.split('=')
|
if let Some(&(parent_start, parent_end)) = config.sections.get(category) {
|
||||||
.nth(1)
|
if parent_start < config.content.len() && parent_end < config.content.len() {
|
||||||
.map(|s| s.trim().to_string())
|
let subsection = format!("{} {{", parts[0]);
|
||||||
.unwrap_or_default();
|
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;
|
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);
|
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();
|
let updated_config_str = parsed_config.to_string();
|
||||||
|
|
||||||
match fs::write(&path, updated_config_str) {
|
match fs::write(&path, updated_config_str) {
|
||||||
Ok(_) => println!("Configuration saved to: ~/{}", CONFIG_PATH),
|
Ok(_) => println!("Configuration saved successfully"),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
gui_ref.custom_error_popup(
|
gui_ref.custom_error_popup(
|
||||||
"Saving failed",
|
"Saving failed",
|
||||||
@@ -151,13 +171,54 @@ fn undo_changes(gui: Rc<RefCell<gui::ConfigGUI>>) {
|
|||||||
));
|
));
|
||||||
|
|
||||||
if backup_path.exists() {
|
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) {
|
match fs::copy(&backup_path, &path) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
println!("Configuration restored from backup");
|
|
||||||
if let Ok(config_str) = fs::read_to_string(&path) {
|
if let Ok(config_str) = fs::read_to_string(&path) {
|
||||||
let parsed_config = parse_config(&config_str);
|
let parsed_config = parse_config(&config_str);
|
||||||
gui_ref.load_config(&parsed_config);
|
gui_ref.load_config(&parsed_config);
|
||||||
|
|
||||||
gui_ref.get_changes().borrow_mut().clear();
|
gui_ref.get_changes().borrow_mut().clear();
|
||||||
|
|
||||||
if let Err(e) = fs::remove_file(&backup_path) {
|
if let Err(e) = fs::remove_file(&backup_path) {
|
||||||
@@ -169,7 +230,7 @@ fn undo_changes(gui: Rc<RefCell<gui::ConfigGUI>>) {
|
|||||||
} else {
|
} else {
|
||||||
gui_ref.custom_info_popup(
|
gui_ref.custom_info_popup(
|
||||||
"Undo Successful",
|
"Undo Successful",
|
||||||
"Configuration restored from backup and backup file deleted.",
|
"Configuration restored from backup and backup files deleted.",
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user