Skip to content

Commit

Permalink
add support for sourced files (#57)
Browse files Browse the repository at this point in the history
* add functionality needed for sourced files to work

* fix entry handling

* run fmt

* allow dead code

* fix nested entries

* fix nested option filling
  • Loading branch information
nnyyxxxx authored Nov 1, 2024
1 parent 204f109 commit 4f3dd91
Show file tree
Hide file tree
Showing 2 changed files with 171 additions and 14 deletions.
116 changes: 106 additions & 10 deletions src/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
}
}
}

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(&section_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;
}
}
}
String::new()

value
}
}
69 changes: 65 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,34 @@ 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);

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",
Expand All @@ -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) {
Expand All @@ -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,
);
}
Expand Down

0 comments on commit 4f3dd91

Please sign in to comment.