mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-07-03 11:41:45 +02:00
304158cb1f
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
171 lines
5.6 KiB
Rust
171 lines
5.6 KiB
Rust
use clap::ArgEnum;
|
|
use color_eyre::Result;
|
|
use schemars::JsonSchema;
|
|
use serde::Deserialize;
|
|
use serde::Serialize;
|
|
use strum::Display;
|
|
use strum::EnumString;
|
|
|
|
use crate::ApplicationIdentifier;
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, Display, EnumString, ArgEnum, JsonSchema)]
|
|
#[strum(serialize_all = "snake_case")]
|
|
#[serde(rename_all = "snake_case")]
|
|
pub enum ApplicationOptions {
|
|
ObjectNameChange,
|
|
Layered,
|
|
BorderOverflow,
|
|
TrayAndMultiWindow,
|
|
Force,
|
|
}
|
|
|
|
impl ApplicationOptions {
|
|
#[must_use]
|
|
pub fn cfgen(&self, kind: &ApplicationIdentifier, id: &str) -> String {
|
|
format!(
|
|
"Run, {}, , Hide",
|
|
match self {
|
|
ApplicationOptions::ObjectNameChange => {
|
|
format!(
|
|
"komorebic.exe identify-object-name-change-application {} {}",
|
|
kind, id
|
|
)
|
|
}
|
|
ApplicationOptions::Layered => {
|
|
format!("komorebic.exe identify-layered-application {} {}", kind, id)
|
|
}
|
|
ApplicationOptions::BorderOverflow => {
|
|
format!(
|
|
"komorebic.exe identify-border-overflow-application {} {}",
|
|
kind, id
|
|
)
|
|
}
|
|
ApplicationOptions::TrayAndMultiWindow => {
|
|
format!("komorebic.exe identify-tray-application {} {}", kind, id)
|
|
}
|
|
ApplicationOptions::Force => {
|
|
format!("komorebic.exe manage-rule {} {}", kind, id)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
|
pub struct IdWithIdentifier {
|
|
kind: ApplicationIdentifier,
|
|
id: String,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
|
pub struct IdWithIdentifierAndComment {
|
|
kind: ApplicationIdentifier,
|
|
id: String,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
comment: Option<String>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
|
pub struct ApplicationConfiguration {
|
|
name: String,
|
|
identifier: IdWithIdentifier,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
options: Option<Vec<ApplicationOptions>>,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
float_identifiers: Option<Vec<IdWithIdentifierAndComment>>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
|
pub struct ApplicationConfigurationGenerator;
|
|
|
|
impl ApplicationConfigurationGenerator {
|
|
fn load(content: &str) -> Result<Vec<ApplicationConfiguration>> {
|
|
Ok(serde_yaml::from_str(content)?)
|
|
}
|
|
|
|
pub fn format(content: &str) -> Result<String> {
|
|
let mut cfgen = Self::load(content)?;
|
|
cfgen.sort_by(|a, b| a.name.cmp(&b.name));
|
|
Ok(serde_yaml::to_string(&cfgen)?)
|
|
}
|
|
|
|
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![
|
|
String::from("; Generated by komorebic.exe"),
|
|
String::from("; To use this file, add the line below to the top of your komorebi.ahk configuration file"),
|
|
String::from("; #Include %A_ScriptDir%\\komorebi.generated.ahk"),
|
|
String::from("")
|
|
];
|
|
|
|
let mut float_rules = vec![];
|
|
|
|
for app in cfgen {
|
|
lines.push(format!("; {}", app.name));
|
|
if let Some(options) = app.options {
|
|
for opt in options {
|
|
if let ApplicationOptions::TrayAndMultiWindow = opt {
|
|
lines.push(String::from("; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line"));
|
|
}
|
|
|
|
lines.push(opt.cfgen(&app.identifier.kind, &app.identifier.id));
|
|
}
|
|
}
|
|
|
|
if let Some(float_identifiers) = app.float_identifiers {
|
|
for float in float_identifiers {
|
|
let float_rule = format!(
|
|
"Run, komorebic.exe float-rule {} {}, , Hide",
|
|
float.kind, float.id
|
|
);
|
|
|
|
// Don't want to send duped signals especially as configs get larger
|
|
if !float_rules.contains(&float_rule) {
|
|
float_rules.push(float_rule.clone());
|
|
|
|
if let Some(comment) = float.comment {
|
|
lines.push(format!("; {}", comment));
|
|
};
|
|
|
|
lines.push(float_rule);
|
|
}
|
|
}
|
|
}
|
|
|
|
lines.push(String::from(""));
|
|
}
|
|
|
|
Ok(lines)
|
|
}
|
|
}
|