feat(config): add cfgen override merging

This commit adds a second optional argument to the ahk-asc command which
can take an override yaml file. This file can include either entirely
new entries that are not suitable for the asc definitions in the
community repo, or overrides for entries that exist in the community asc
definitions files which will take precedence in the generated ahk file.

This can be useful for example, when the default behaviour for an app is
to minimise to system tray, but that option has been disabled on a
user's computer, making the 'tray_and_multi_window' option no longer
appropriate for their komorebi configuration.

In the case of wanting to override an existing entry, only the "name"
key needs to match; upon a match the entry from the community asc
definitions will be entirely replaced with the entry from the override
definitions.

re #62
This commit is contained in:
LGUG2Z
2022-04-03 18:16:35 -07:00
parent c426c06c01
commit 304158cb1f
3 changed files with 52 additions and 19 deletions

View File

@@ -89,8 +89,36 @@ impl ApplicationConfigurationGenerator {
Ok(serde_yaml::to_string(&cfgen)?)
}
pub fn generate_ahk(content: &str) -> Result<Vec<String>> {
let mut cfgen = Self::load(content)?;
fn merge(base_content: &str, override_content: &str) -> Result<Vec<ApplicationConfiguration>> {
let base_cfgen = Self::load(base_content)?;
let override_cfgen = Self::load(override_content)?;
let mut final_cfgen = base_cfgen.clone();
for entry in override_cfgen {
let mut replace_idx = None;
for (idx, base_entry) in base_cfgen.iter().enumerate() {
if base_entry.name == entry.name {
replace_idx = Option::from(idx);
}
}
match replace_idx {
None => final_cfgen.push(entry),
Some(idx) => final_cfgen[idx] = entry,
}
}
Ok(final_cfgen)
}
pub fn generate_ahk(base_content: &str, override_content: Option<&str>) -> Result<Vec<String>> {
let mut cfgen = if let Some(override_content) = override_content {
Self::merge(base_content, override_content)?
} else {
Self::load(base_content)?
};
cfgen.sort_by(|a, b| a.name.cmp(&b.name));
let mut lines = vec![

View File

@@ -304,8 +304,8 @@ AhkLibrary() {
Run, komorebic.exe ahk-library, , Hide
}
AhkAppSpecificConfiguration(path) {
Run, komorebic.exe ahk-app-specific-configuration %path%, , Hide
AhkAppSpecificConfiguration(path, override_path) {
Run, komorebic.exe ahk-app-specific-configuration %path% %override_path%, , Hide
}
FormatAppSpecificConfiguration(path) {

View File

@@ -422,22 +422,18 @@ struct Unsubscribe {
named_pipe: String,
}
macro_rules! gen_application_specific_configuration_subcommand_args {
// SubCommand Pattern
( $( $name:ident ),+ $(,)? ) => {
$(
#[derive(clap::Parser, derive_ahk::AhkFunction)]
pub struct $name {
/// YAML file from which the application-specific configurations should be loaded
path: String,
}
)+
};
#[derive(Parser, AhkFunction)]
struct AhkAppSpecificConfiguration {
/// YAML file from which the application-specific configurations should be loaded
path: String,
/// Optional YAML file of overrides to apply over the first file
override_path: Option<String>,
}
gen_application_specific_configuration_subcommand_args! {
AhkAppSpecificConfiguration,
FormatAppSpecificConfiguration,
#[derive(Parser, AhkFunction)]
struct FormatAppSpecificConfiguration {
/// YAML file from which the application-specific configurations should be loaded
path: String,
}
#[derive(Parser)]
@@ -1165,7 +1161,16 @@ fn main() -> Result<()> {
}
SubCommand::AhkAppSpecificConfiguration(arg) => {
let content = fs::read_to_string(resolve_windows_path(&arg.path)?)?;
let lines = ApplicationConfigurationGenerator::generate_ahk(&content)?;
let lines = if let Some(override_path) = arg.override_path {
let override_content = fs::read_to_string(resolve_windows_path(&override_path)?)?;
ApplicationConfigurationGenerator::generate_ahk(
&content,
Option::from(override_content.as_str()),
)?
} else {
ApplicationConfigurationGenerator::generate_ahk(&content, None)?
};
let mut generated_config = HOME_DIR.clone();
generated_config.push("komorebi.generated.ahk");