diff --git a/Cargo.lock b/Cargo.lock index 7c30e665..44f7913a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -515,6 +515,7 @@ dependencies = [ "fs-tail", "heck 0.4.0", "komorebi-core", + "lazy_static", "paste", "powershell_script", "serde", diff --git a/README.md b/README.md index 511c0111..1e5eae73 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,32 @@ for _komorebi_ can be found [here](https://gist.github.com/crosstyan/dafacc0778d ### Common First-Time Tips +#### Setting a Custom KOMOREBI_CONFIG_HOME Directory + +If you do not want to keep _komorebi_-related files in your `$Env:UserProfile` directory, you can specify a custom directory +by setting the `$Env:KOMOREBI_CONFIG_HOME` environment variable. + +For example, to use the `~/.config/komorebi` directory: + +```powershell +# Run this command to make sure that the directory has been created +mkdir -p ~/.config/komorebi + +# Run this command to open up your PowerShell profile configuration in Notepad +notepad $PROFILE + +# Add this line (with your login user!) to the bottom of your PowerShell profile configuration +$Env:KOMOREBI_CONFIG_HOME = 'C:\Users\LGUG2Z\.config\komorebi' + +# Save the changes and then reload the PowerShell profile +. $PROFILE +``` + +If you already have configuration files that you wish to keep, move them to the `~/.config/komorebi` directory. + +The next time you run `komorebic start`, any files created by or loaded by _komorebi_ will be placed or expected to +exist in this folder. + #### Floating Windows Sometimes you will want a specific application to never be tiled, and instead float all the time. You add add rules to diff --git a/justfile b/justfile index e76fa626..045b5512 100644 --- a/justfile +++ b/justfile @@ -19,7 +19,7 @@ install: just install-komorebic just install-komorebi komorebic ahk-library - cat '%USERPROFILE%\komorebic.lib.ahk' > komorebic.lib.sample.ahk + cat '%USERPROFILE%\.config\komorebi\komorebic.lib.ahk' > komorebic.lib.sample.ahk run: just install-komorebic diff --git a/komorebi/src/main.rs b/komorebi/src/main.rs index 3bc374b3..b433fdc1 100644 --- a/komorebi/src/main.rs +++ b/komorebi/src/main.rs @@ -4,6 +4,7 @@ use std::collections::HashMap; use std::fs::File; use std::io::Write; +use std::path::PathBuf; use std::process::Command; use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicU32; @@ -99,6 +100,22 @@ lazy_static! { Arc::new(Mutex::new(HashMap::new())); static ref HIDING_BEHAVIOUR: Arc> = Arc::new(Mutex::new(HidingBehaviour::Minimize)); + static ref HOME_DIR: PathBuf = { + if let Ok(home_path) = std::env::var("KOMOREBI_CONFIG_HOME") { + let home = PathBuf::from(&home_path); + + if home.as_path().is_dir() { + home + } else { + panic!( + "$Env:KOMOREBI_CONFIG_HOME is set to '{}', which is not a valid directory", + home_path + ); + } + } else { + dirs::home_dir().expect("there is no home directory") + } + }; } pub static CUSTOM_FFM: AtomicBool = AtomicBool::new(false); @@ -115,7 +132,7 @@ fn setup() -> Result<(WorkerGuard, WorkerGuard)> { std::env::set_var("RUST_LOG", "info"); } - let home = dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?; + let home = HOME_DIR.clone(); let appender = tracing_appender::rolling::never(home, "komorebi.log"); let color_appender = tracing_appender::rolling::never(std::env::temp_dir(), "komorebi.log"); let (non_blocking, guard) = tracing_appender::non_blocking(appender); @@ -169,7 +186,7 @@ fn setup() -> Result<(WorkerGuard, WorkerGuard)> { } pub fn load_configuration() -> Result<()> { - let home = dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?; + let home = HOME_DIR.clone(); let mut config_v1 = home.clone(); config_v1.push("komorebi.ahk"); diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index ba93e945..46e22124 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -37,6 +37,7 @@ use crate::BORDER_OVERFLOW_IDENTIFIERS; use crate::CUSTOM_FFM; use crate::FLOAT_IDENTIFIERS; use crate::HIDING_BEHAVIOUR; +use crate::HOME_DIR; use crate::MANAGE_IDENTIFIERS; use crate::SUBSCRIPTION_PIPES; use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS; @@ -306,8 +307,7 @@ impl WindowManager { Err(error) => error.to_string(), }; - let mut socket = - dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?; + let mut socket = HOME_DIR.clone(); socket.push("komorebic.sock"); let socket = socket.as_path(); @@ -330,8 +330,7 @@ impl WindowManager { } .to_string(); - let mut socket = - dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?; + let mut socket = HOME_DIR.clone(); socket.push("komorebic.sock"); let socket = socket.as_path(); diff --git a/komorebi/src/process_event.rs b/komorebi/src/process_event.rs index 084ea076..06f9c38a 100644 --- a/komorebi/src/process_event.rs +++ b/komorebi/src/process_event.rs @@ -20,6 +20,7 @@ use crate::windows_api::WindowsApi; use crate::Notification; use crate::NotificationEvent; use crate::HIDDEN_HWNDS; +use crate::HOME_DIR; use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS; #[tracing::instrument] @@ -466,8 +467,7 @@ impl WindowManager { } } - let mut hwnd_json = - dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?; + let mut hwnd_json = HOME_DIR.clone(); hwnd_json.push("komorebi.hwnd.json"); let file = OpenOptions::new() .write(true) diff --git a/komorebi/src/window_manager.rs b/komorebi/src/window_manager.rs index e8a4b4ad..d7b8567c 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -38,6 +38,7 @@ use crate::winevent_listener::WINEVENT_CALLBACK_CHANNEL; use crate::workspace::Workspace; use crate::BORDER_OVERFLOW_IDENTIFIERS; use crate::FLOAT_IDENTIFIERS; +use crate::HOME_DIR; use crate::LAYERED_EXE_WHITELIST; use crate::MANAGE_IDENTIFIERS; use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS; @@ -129,7 +130,7 @@ impl EnforceWorkspaceRuleOp { impl WindowManager { #[tracing::instrument] pub fn new(incoming: Arc>>) -> Result { - let home = dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?; + let home = HOME_DIR.clone(); let mut socket = home; socket.push("komorebi.sock"); let socket = socket.as_path(); @@ -186,7 +187,7 @@ impl WindowManager { #[tracing::instrument(skip(self))] pub fn watch_configuration(&mut self, enable: bool) -> Result<()> { - let home = dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?; + let home = HOME_DIR.clone(); let mut config_v1 = home.clone(); config_v1.push("komorebi.ahk"); diff --git a/komorebic/Cargo.toml b/komorebic/Cargo.toml index eea00c4f..7df6c4d4 100644 --- a/komorebic/Cargo.toml +++ b/komorebic/Cargo.toml @@ -19,6 +19,7 @@ color-eyre = "0.5" dirs = "4" fs-tail = "0.1" heck = "0.4" +lazy_static = "1" paste = "1" powershell_script = "0.2" serde = { version = "1", features = ["derive"] } diff --git a/komorebic/src/main.rs b/komorebic/src/main.rs index 0a114da1..06f6ddf5 100644 --- a/komorebic/src/main.rs +++ b/komorebic/src/main.rs @@ -17,6 +17,7 @@ use color_eyre::eyre::anyhow; use color_eyre::Result; use fs_tail::TailedFile; use heck::ToKebabCase; +use lazy_static::lazy_static; use paste::paste; use uds_windows::UnixListener; use uds_windows::UnixStream; @@ -39,6 +40,25 @@ use komorebi_core::Sizing; use komorebi_core::SocketMessage; use komorebi_core::StateQuery; +lazy_static! { + static ref HOME_DIR: PathBuf = { + if let Ok(home_path) = std::env::var("KOMOREBI_CONFIG_HOME") { + let home = PathBuf::from(&home_path); + + if home.as_path().is_dir() { + home + } else { + panic!( + "$Env:KOMOREBI_CONFIG_HOME is set to '{}', which is not a valid directory", + home_path + ); + } + } else { + dirs::home_dir().expect("there is no home directory") + } + }; +} + trait AhkLibrary { fn generate_ahk_library() -> String; } @@ -557,7 +577,7 @@ enum SubCommand { } pub fn send_message(bytes: &[u8]) -> Result<()> { - let mut socket = dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?; + let mut socket = HOME_DIR.clone(); socket.push("komorebi.sock"); let socket = socket.as_path(); @@ -571,8 +591,7 @@ fn main() -> Result<()> { match opts.subcmd { SubCommand::AhkLibrary => { - let mut library = - dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?; + let mut library = HOME_DIR.clone(); library.push("komorebic.lib.ahk"); let mut file = OpenOptions::new() .write(true) @@ -846,7 +865,7 @@ fn main() -> Result<()> { )?; } SubCommand::State => { - let home = dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?; + let home = HOME_DIR.clone(); let mut socket = home; socket.push("komorebic.sock"); let socket = socket.as_path(); @@ -880,7 +899,7 @@ fn main() -> Result<()> { } } SubCommand::Query(arg) => { - let home = dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?; + let home = HOME_DIR.clone(); let mut socket = home; socket.push("komorebic.sock"); let socket = socket.as_path(); @@ -914,8 +933,7 @@ fn main() -> Result<()> { } } SubCommand::RestoreWindows => { - let mut hwnd_json = - dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?; + let mut hwnd_json = HOME_DIR.clone(); hwnd_json.push("komorebi.hwnd.json"); let file = File::open(hwnd_json)?;