From bf593b4a742a653191920202be59bb5edec61d00 Mon Sep 17 00:00:00 2001 From: OneNoted Date: Thu, 19 Feb 2026 20:29:49 +0100 Subject: [PATCH 1/4] feat: add data_dir config option for custom PrismLauncher directory --- src/app.rs | 4 +--- src/data/app_config.rs | 20 ++++++++++++++++++++ src/data/config.rs | 19 +++++++++++++++---- src/main.rs | 7 ++++--- 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/app.rs b/src/app.rs index 66abd0b..7f66480 100644 --- a/src/app.rs +++ b/src/app.rs @@ -203,7 +203,7 @@ pub struct App { } impl App { - pub fn new(config: PrismConfig) -> Result { + pub fn new(config: PrismConfig, app_config: AppConfig) -> Result { use crate::data::{load_accounts, load_groups, load_instances}; let instances_dir = config.instances_dir(); @@ -213,8 +213,6 @@ impl App { let active_account = accounts.iter().find(|a| a.is_active).cloned(); - let app_config = AppConfig::load(); - let sort_mode = app_config.default_sort_mode(); let sort_ascending = app_config.sort_ascending; diff --git a/src/data/app_config.rs b/src/data/app_config.rs index 65391eb..271748b 100644 --- a/src/data/app_config.rs +++ b/src/data/app_config.rs @@ -9,6 +9,8 @@ pub struct AppConfig { pub default_sort: String, #[serde(default = "default_true")] pub sort_ascending: bool, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub data_dir: Option, } fn default_true() -> bool { @@ -24,6 +26,7 @@ impl Default for AppConfig { Self { default_sort: default_sort(), sort_ascending: true, + data_dir: None, } } } @@ -65,6 +68,10 @@ impl AppConfig { } } + pub fn resolved_data_dir(&self) -> Option { + self.data_dir.as_ref().map(|p| expand_tilde(p)) + } + pub fn default_sort_mode(&self) -> SortMode { match self.default_sort.as_str() { "Name" => SortMode::Name, @@ -75,3 +82,16 @@ impl AppConfig { } } } + +fn expand_tilde(path: &str) -> PathBuf { + if let Some(rest) = path.strip_prefix("~/") { + if let Some(home) = dirs::home_dir() { + return home.join(rest); + } + } else if path == "~" { + if let Some(home) = dirs::home_dir() { + return home; + } + } + PathBuf::from(path) +} diff --git a/src/data/config.rs b/src/data/config.rs index 78fb382..93dbfc5 100644 --- a/src/data/config.rs +++ b/src/data/config.rs @@ -38,8 +38,8 @@ impl PrismConfig { } } -pub fn find_prism_data_dir() -> Result { - // Check environment variable first +pub fn find_prism_data_dir(config_data_dir: Option) -> Result { + // 1. Check environment variable first if let Ok(path) = env::var("PRISMLAUNCHER_DATA") { let path = PathBuf::from(path); if path.exists() { @@ -47,7 +47,18 @@ pub fn find_prism_data_dir() -> Result { } } - // Standard location + // 2. Config file data_dir + if let Some(path) = config_data_dir { + if path.exists() { + return Ok(path); + } + return Err(PrismError::Config(format!( + "Configured data_dir does not exist: {}", + path.display() + ))); + } + + // 3. Standard platform location if let Some(data_dir) = dirs::data_dir() { let standard = data_dir.join("PrismLauncher"); if standard.exists() { @@ -55,7 +66,7 @@ pub fn find_prism_data_dir() -> Result { } } - // Flatpak location (Linux only) + // 4. Flatpak location (Linux only) #[cfg(target_os = "linux")] { if let Some(home) = dirs::home_dir() { diff --git a/src/main.rs b/src/main.rs index e4ec5b9..a9bf142 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ mod view; use app::App; use color_eyre::Result; -use data::{PrismConfig, find_prism_data_dir}; +use data::{AppConfig, PrismConfig, find_prism_data_dir}; use message::Message; use std::time::Duration; use tui::{Event, EventStream, Terminal}; @@ -19,9 +19,10 @@ use tui::{Event, EventStream, Terminal}; async fn main() -> Result<()> { color_eyre::install()?; - let data_dir = find_prism_data_dir()?; + let app_config = AppConfig::load(); + let data_dir = find_prism_data_dir(app_config.resolved_data_dir())?; let config = PrismConfig::load(&data_dir)?; - let mut app = App::new(config)?; + let mut app = App::new(config, app_config)?; let mut terminal = Terminal::new()?; let mut events = EventStream::new(Duration::from_millis(250)); From c4a6a2d163596e8b831f49294676f4aeecac224b Mon Sep 17 00:00:00 2001 From: OneNoted Date: Thu, 19 Feb 2026 20:34:01 +0100 Subject: [PATCH 2/4] fix: add Windows tilde expansion and consistent error for missing data dirs --- src/data/app_config.rs | 3 ++- src/data/config.rs | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/data/app_config.rs b/src/data/app_config.rs index 271748b..8d7370e 100644 --- a/src/data/app_config.rs +++ b/src/data/app_config.rs @@ -84,7 +84,8 @@ impl AppConfig { } fn expand_tilde(path: &str) -> PathBuf { - if let Some(rest) = path.strip_prefix("~/") { + let rest = path.strip_prefix("~/").or_else(|| path.strip_prefix("~\\")); + if let Some(rest) = rest { if let Some(home) = dirs::home_dir() { return home.join(rest); } diff --git a/src/data/config.rs b/src/data/config.rs index 93dbfc5..a6951e0 100644 --- a/src/data/config.rs +++ b/src/data/config.rs @@ -45,6 +45,10 @@ pub fn find_prism_data_dir(config_data_dir: Option) -> Result if path.exists() { return Ok(path); } + return Err(PrismError::Config(format!( + "PRISMLAUNCHER_DATA directory does not exist: {}", + path.display() + ))); } // 2. Config file data_dir From 77a01ddf06e4dd5ab1ab7f9cea5adcac7a096897 Mon Sep 17 00:00:00 2001 From: OneNoted Date: Thu, 19 Feb 2026 20:35:13 +0100 Subject: [PATCH 3/4] docs: document data_dir config option and config file location --- README.md | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2219fd7..e51bfb7 100644 --- a/README.md +++ b/README.md @@ -103,13 +103,34 @@ Press `/` to enter search mode. Type to filter the list incrementally. Press `En ## Configuration -prism-tui reads its configuration from PrismLauncher's data directory: +### PrismLauncher Data Directory -- **Linux**: `~/.local/share/PrismLauncher/` +prism-tui automatically detects your PrismLauncher data directory: + +- **Linux**: `~/.local/share/PrismLauncher/` or Flatpak location - **macOS**: `~/Library/Application Support/PrismLauncher/` - **Windows**: `%APPDATA%/PrismLauncher/` -No additional configuration is required. +For custom or portable installations, you can override the data directory in two ways (checked in this order): + +1. **Environment variable**: `PRISMLAUNCHER_DATA=/path/to/data prism-tui` +2. **Config file**: Set `data_dir` in the config (see below) + +### Config File + +prism-tui stores its settings in a TOML config file: + +- **Linux**: `~/.config/prism-tui/config.toml` +- **macOS**: `~/Library/Application Support/prism-tui/config.toml` +- **Windows**: `%APPDATA%\prism-tui\config.toml` + +```toml +default_sort = "Last Played" +sort_ascending = true +data_dir = "~/Games/PrismLauncher" # optional, overrides auto-detection +``` + +Sort and sort-direction preferences are saved automatically. The `data_dir` option supports `~` tilde expansion. ## Architecture From 73b75fe07f319a95fcdd377cac465ac5873a1fa8 Mon Sep 17 00:00:00 2001 From: OneNoted Date: Thu, 19 Feb 2026 20:40:41 +0100 Subject: [PATCH 4/4] style: fix collapsible_if clippy lint in expand_tilde --- src/data/app_config.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/data/app_config.rs b/src/data/app_config.rs index 8d7370e..ddca2c5 100644 --- a/src/data/app_config.rs +++ b/src/data/app_config.rs @@ -89,10 +89,10 @@ fn expand_tilde(path: &str) -> PathBuf { if let Some(home) = dirs::home_dir() { return home.join(rest); } - } else if path == "~" { - if let Some(home) = dirs::home_dir() { - return home; - } + } else if path == "~" + && let Some(home) = dirs::home_dir() + { + return home; } PathBuf::from(path) }