feat(config): allow users to define config dir

This commit introduces a change to allow users to set a custom
configuration directory for Komorebi to address concerns about $HOME
getting cluttered.

The custom directory can be set with the environment variable
$Env:KOMOREBI_CONFIG_HOME (this should probably be done in $PROFILE).

If this variable is not set, komorebi will default to using
the $HOME directory.

resolve #61
This commit is contained in:
LGUG2Z
2022-01-28 09:27:31 -08:00
parent e67425f841
commit 43b2366378
9 changed files with 81 additions and 18 deletions
Generated
+1
View File
@@ -515,6 +515,7 @@ dependencies = [
"fs-tail", "fs-tail",
"heck 0.4.0", "heck 0.4.0",
"komorebi-core", "komorebi-core",
"lazy_static",
"paste", "paste",
"powershell_script", "powershell_script",
"serde", "serde",
+26
View File
@@ -140,6 +140,32 @@ for _komorebi_ can be found [here](https://gist.github.com/crosstyan/dafacc0778d
### Common First-Time Tips ### 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 #### Floating Windows
Sometimes you will want a specific application to never be tiled, and instead float all the time. You add add rules to Sometimes you will want a specific application to never be tiled, and instead float all the time. You add add rules to
+1 -1
View File
@@ -19,7 +19,7 @@ install:
just install-komorebic just install-komorebic
just install-komorebi just install-komorebi
komorebic ahk-library komorebic ahk-library
cat '%USERPROFILE%\komorebic.lib.ahk' > komorebic.lib.sample.ahk cat '%USERPROFILE%\.config\komorebi\komorebic.lib.ahk' > komorebic.lib.sample.ahk
run: run:
just install-komorebic just install-komorebic
+19 -2
View File
@@ -4,6 +4,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
use std::path::PathBuf;
use std::process::Command; use std::process::Command;
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;
use std::sync::atomic::AtomicU32; use std::sync::atomic::AtomicU32;
@@ -99,6 +100,22 @@ lazy_static! {
Arc::new(Mutex::new(HashMap::new())); Arc::new(Mutex::new(HashMap::new()));
static ref HIDING_BEHAVIOUR: Arc<Mutex<HidingBehaviour>> = static ref HIDING_BEHAVIOUR: Arc<Mutex<HidingBehaviour>> =
Arc::new(Mutex::new(HidingBehaviour::Minimize)); 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); pub static CUSTOM_FFM: AtomicBool = AtomicBool::new(false);
@@ -115,7 +132,7 @@ fn setup() -> Result<(WorkerGuard, WorkerGuard)> {
std::env::set_var("RUST_LOG", "info"); 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 appender = tracing_appender::rolling::never(home, "komorebi.log");
let color_appender = tracing_appender::rolling::never(std::env::temp_dir(), "komorebi.log"); let color_appender = tracing_appender::rolling::never(std::env::temp_dir(), "komorebi.log");
let (non_blocking, guard) = tracing_appender::non_blocking(appender); let (non_blocking, guard) = tracing_appender::non_blocking(appender);
@@ -169,7 +186,7 @@ fn setup() -> Result<(WorkerGuard, WorkerGuard)> {
} }
pub fn load_configuration() -> Result<()> { 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(); let mut config_v1 = home.clone();
config_v1.push("komorebi.ahk"); config_v1.push("komorebi.ahk");
+3 -4
View File
@@ -37,6 +37,7 @@ use crate::BORDER_OVERFLOW_IDENTIFIERS;
use crate::CUSTOM_FFM; use crate::CUSTOM_FFM;
use crate::FLOAT_IDENTIFIERS; use crate::FLOAT_IDENTIFIERS;
use crate::HIDING_BEHAVIOUR; use crate::HIDING_BEHAVIOUR;
use crate::HOME_DIR;
use crate::MANAGE_IDENTIFIERS; use crate::MANAGE_IDENTIFIERS;
use crate::SUBSCRIPTION_PIPES; use crate::SUBSCRIPTION_PIPES;
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS; use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
@@ -306,8 +307,7 @@ impl WindowManager {
Err(error) => error.to_string(), Err(error) => error.to_string(),
}; };
let mut socket = let mut socket = HOME_DIR.clone();
dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?;
socket.push("komorebic.sock"); socket.push("komorebic.sock");
let socket = socket.as_path(); let socket = socket.as_path();
@@ -330,8 +330,7 @@ impl WindowManager {
} }
.to_string(); .to_string();
let mut socket = let mut socket = HOME_DIR.clone();
dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?;
socket.push("komorebic.sock"); socket.push("komorebic.sock");
let socket = socket.as_path(); let socket = socket.as_path();
+2 -2
View File
@@ -20,6 +20,7 @@ use crate::windows_api::WindowsApi;
use crate::Notification; use crate::Notification;
use crate::NotificationEvent; use crate::NotificationEvent;
use crate::HIDDEN_HWNDS; use crate::HIDDEN_HWNDS;
use crate::HOME_DIR;
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS; use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
#[tracing::instrument] #[tracing::instrument]
@@ -466,8 +467,7 @@ impl WindowManager {
} }
} }
let mut hwnd_json = let mut hwnd_json = HOME_DIR.clone();
dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?;
hwnd_json.push("komorebi.hwnd.json"); hwnd_json.push("komorebi.hwnd.json");
let file = OpenOptions::new() let file = OpenOptions::new()
.write(true) .write(true)
+3 -2
View File
@@ -38,6 +38,7 @@ use crate::winevent_listener::WINEVENT_CALLBACK_CHANNEL;
use crate::workspace::Workspace; use crate::workspace::Workspace;
use crate::BORDER_OVERFLOW_IDENTIFIERS; use crate::BORDER_OVERFLOW_IDENTIFIERS;
use crate::FLOAT_IDENTIFIERS; use crate::FLOAT_IDENTIFIERS;
use crate::HOME_DIR;
use crate::LAYERED_EXE_WHITELIST; use crate::LAYERED_EXE_WHITELIST;
use crate::MANAGE_IDENTIFIERS; use crate::MANAGE_IDENTIFIERS;
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS; use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
@@ -129,7 +130,7 @@ impl EnforceWorkspaceRuleOp {
impl WindowManager { impl WindowManager {
#[tracing::instrument] #[tracing::instrument]
pub fn new(incoming: Arc<Mutex<Receiver<WindowManagerEvent>>>) -> Result<Self> { pub fn new(incoming: Arc<Mutex<Receiver<WindowManagerEvent>>>) -> Result<Self> {
let home = dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?; let home = HOME_DIR.clone();
let mut socket = home; let mut socket = home;
socket.push("komorebi.sock"); socket.push("komorebi.sock");
let socket = socket.as_path(); let socket = socket.as_path();
@@ -186,7 +187,7 @@ impl WindowManager {
#[tracing::instrument(skip(self))] #[tracing::instrument(skip(self))]
pub fn watch_configuration(&mut self, enable: bool) -> Result<()> { 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(); let mut config_v1 = home.clone();
config_v1.push("komorebi.ahk"); config_v1.push("komorebi.ahk");
+1
View File
@@ -19,6 +19,7 @@ color-eyre = "0.5"
dirs = "4" dirs = "4"
fs-tail = "0.1" fs-tail = "0.1"
heck = "0.4" heck = "0.4"
lazy_static = "1"
paste = "1" paste = "1"
powershell_script = "0.2" powershell_script = "0.2"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
+25 -7
View File
@@ -17,6 +17,7 @@ use color_eyre::eyre::anyhow;
use color_eyre::Result; use color_eyre::Result;
use fs_tail::TailedFile; use fs_tail::TailedFile;
use heck::ToKebabCase; use heck::ToKebabCase;
use lazy_static::lazy_static;
use paste::paste; use paste::paste;
use uds_windows::UnixListener; use uds_windows::UnixListener;
use uds_windows::UnixStream; use uds_windows::UnixStream;
@@ -39,6 +40,25 @@ use komorebi_core::Sizing;
use komorebi_core::SocketMessage; use komorebi_core::SocketMessage;
use komorebi_core::StateQuery; 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 { trait AhkLibrary {
fn generate_ahk_library() -> String; fn generate_ahk_library() -> String;
} }
@@ -557,7 +577,7 @@ enum SubCommand {
} }
pub fn send_message(bytes: &[u8]) -> Result<()> { 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"); socket.push("komorebi.sock");
let socket = socket.as_path(); let socket = socket.as_path();
@@ -571,8 +591,7 @@ fn main() -> Result<()> {
match opts.subcmd { match opts.subcmd {
SubCommand::AhkLibrary => { SubCommand::AhkLibrary => {
let mut library = let mut library = HOME_DIR.clone();
dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?;
library.push("komorebic.lib.ahk"); library.push("komorebic.lib.ahk");
let mut file = OpenOptions::new() let mut file = OpenOptions::new()
.write(true) .write(true)
@@ -846,7 +865,7 @@ fn main() -> Result<()> {
)?; )?;
} }
SubCommand::State => { 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; let mut socket = home;
socket.push("komorebic.sock"); socket.push("komorebic.sock");
let socket = socket.as_path(); let socket = socket.as_path();
@@ -880,7 +899,7 @@ fn main() -> Result<()> {
} }
} }
SubCommand::Query(arg) => { 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; let mut socket = home;
socket.push("komorebic.sock"); socket.push("komorebic.sock");
let socket = socket.as_path(); let socket = socket.as_path();
@@ -914,8 +933,7 @@ fn main() -> Result<()> {
} }
} }
SubCommand::RestoreWindows => { SubCommand::RestoreWindows => {
let mut hwnd_json = let mut hwnd_json = HOME_DIR.clone();
dirs::home_dir().ok_or_else(|| anyhow!("there is no home directory"))?;
hwnd_json.push("komorebi.hwnd.json"); hwnd_json.push("komorebi.hwnd.json");
let file = File::open(hwnd_json)?; let file = File::open(hwnd_json)?;