From ce50c148f675821c6f917fa703bd1bfce0ba4580 Mon Sep 17 00:00:00 2001 From: RoomWithOutRoof <166608075+Jah-yee@users.noreply.github.com> Date: Tue, 3 Mar 2026 10:35:38 +0800 Subject: [PATCH 1/4] feat(cli): add -r/--subreddit to open at subreddit Parse -r/--subreddit NAME and pass initial_subreddit to run(); ui selects that sub on startup (insert into list if missing). Fixes #31. Made-with: Cursor --- src/app.rs | 11 ++++++++++- src/lib.rs | 2 +- src/main.rs | 54 +++++++++++++++++++++++++++++++++-------------------- src/ui.rs | 17 +++++++++++++++++ 4 files changed, 62 insertions(+), 22 deletions(-) diff --git a/src/app.rs b/src/app.rs index ea01871..0cba7d5 100644 --- a/src/app.rs +++ b/src/app.rs @@ -12,7 +12,15 @@ use crate::storage; use crate::theme; use crate::ui; -pub fn run() -> Result<()> { +/// Options for the main run entry point (e.g. from CLI). +#[derive(Default)] +pub struct RunOptions { + /// If set, open with this subreddit selected (e.g. "apple" or "r/apple"). + pub initial_subreddit: Option, +} + +pub fn run(options: Option) -> Result<()> { + let run_opts = options.unwrap_or_default(); let cfg = config::load(config::LoadOptions::default()).context("load config")?; let config_path = config::default_path(); let display_path = friendly_path(config_path.as_ref()); @@ -157,6 +165,7 @@ pub fn run() -> Result<()> { session_manager: session_manager.clone(), fetch_subreddits_on_start, theme: theme::palette_for(theme), + initial_subreddit: run_opts.initial_subreddit, }; let mut model = ui::Model::new(options); diff --git a/src/lib.rs b/src/lib.rs index b4de8e5..cf5d481 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,4 +17,4 @@ pub mod video; pub const VERSION: &str = env!("CARGO_PKG_VERSION"); -pub use app::run; +pub use app::{run, RunOptions}; diff --git a/src/main.rs b/src/main.rs index a4500b8..cec588a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,39 +1,53 @@ fn main() { - if handle_cli_flags() { - return; - } - - if let Err(err) = reddix::run() { - eprintln!("error: {err:?}"); - std::process::exit(1); - } -} - -fn handle_cli_flags() -> bool { - let mut saw_flag = false; - for arg in std::env::args().skip(1) { - match arg.as_str() { + let args: Vec = std::env::args().collect(); + let mut initial_subreddit: Option = None; + let mut i = 1; + while i < args.len() { + match args[i].as_str() { "--version" | "-V" => { println!("Reddix {}", reddix::VERSION); - saw_flag = true; + return; } "--help" | "-h" => { println!( - "Reddix — Reddit, refined for the terminal.\n\n --version, -V Show version and exit\n --help, -h Show this help message\n --check-updates Check for updates and exit" + "Reddix — Reddit, refined for the terminal.\n\n --version, -V Show version and exit\n --help, -h Show this help message\n -r, --subreddit NAME Open with this subreddit selected (e.g. -r apple)\n --check-updates Check for updates and exit" ); - saw_flag = true; + return; + } + "-r" | "--subreddit" => { + i += 1; + if i < args.len() && !args[i].starts_with('-') { + initial_subreddit = Some(args[i].clone()); + } + i += 1; + continue; } "--check-updates" => { - saw_flag = true; if let Err(err) = check_updates_once() { eprintln!("Update check failed: {err:?}"); std::process::exit(1); } + return; + } + _ => { + i += 1; } - _ => {} } } - saw_flag + + let run_opts = if initial_subreddit.is_some() { + Some(reddix::RunOptions { + initial_subreddit, + ..Default::default() + }) + } else { + None + }; + + if let Err(err) = reddix::run(run_opts) { + eprintln!("error: {err:?}"); + std::process::exit(1); + } } fn check_updates_once() -> anyhow::Result<()> { diff --git a/src/ui.rs b/src/ui.rs index d76f79a..ee8ba5b 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -3517,6 +3517,8 @@ pub struct Options { pub session_manager: Option>, pub fetch_subreddits_on_start: bool, pub theme: crate::theme::Palette, + /// If set, open with this subreddit selected (e.g. "apple" or "r/apple"). + pub initial_subreddit: Option, } pub struct Model { @@ -4577,6 +4579,21 @@ impl Model { .iter() .position(|name| name.eq_ignore_ascii_case("r/frontpage")) .unwrap_or(0); + if let Some(ref name) = opts.initial_subreddit { + let normalized = normalize_subreddit_name(name); + if normalized != "r/frontpage" { + if let Some(idx) = model + .subreddits + .iter() + .position(|s| s.eq_ignore_ascii_case(&normalized)) + { + model.selected_sub = idx; + } else { + model.subreddits.push(normalized); + model.selected_sub = model.subreddits.len().saturating_sub(1); + } + } + } model.selected_post = 0; model.selected_comment = 0; model.post_offset.set(0); From 86c03dd6ae6018da02939adff14166d41163aa8c Mon Sep 17 00:00:00 2001 From: RoomWithOutRoof <166608075+Jah-yee@users.noreply.github.com> Date: Tue, 3 Mar 2026 10:36:11 +0800 Subject: [PATCH 2/4] feat(cli): add --config PATH to use custom config file Made-with: Cursor --- src/app.rs | 13 +++++++++++-- src/main.rs | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/app.rs b/src/app.rs index 0cba7d5..705a32b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -17,12 +17,21 @@ use crate::ui; pub struct RunOptions { /// If set, open with this subreddit selected (e.g. "apple" or "r/apple"). pub initial_subreddit: Option, + /// If set, load config from this path instead of the default. + pub config_file: Option, } pub fn run(options: Option) -> Result<()> { let run_opts = options.unwrap_or_default(); - let cfg = config::load(config::LoadOptions::default()).context("load config")?; - let config_path = config::default_path(); + let load_opts = config::LoadOptions { + config_file: run_opts.config_file.clone(), + env_prefix: None, + }; + let cfg = config::load(load_opts).context("load config")?; + let config_path = run_opts + .config_file + .clone() + .or_else(config::default_path); let display_path = friendly_path(config_path.as_ref()); ui::configure_terminal_cell_metrics_override(cfg.ui.cell_width, cfg.ui.cell_height); diff --git a/src/main.rs b/src/main.rs index cec588a..9c04793 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ fn main() { let args: Vec = std::env::args().collect(); let mut initial_subreddit: Option = None; + let mut config_file: Option = None; let mut i = 1; while i < args.len() { match args[i].as_str() { @@ -10,10 +11,18 @@ fn main() { } "--help" | "-h" => { println!( - "Reddix — Reddit, refined for the terminal.\n\n --version, -V Show version and exit\n --help, -h Show this help message\n -r, --subreddit NAME Open with this subreddit selected (e.g. -r apple)\n --check-updates Check for updates and exit" + "Reddix — Reddit, refined for the terminal.\n\n --version, -V Show version and exit\n --help, -h Show this help message\n -r, --subreddit NAME Open with this subreddit selected (e.g. -r apple)\n --config PATH Use config file at PATH\n --check-updates Check for updates and exit" ); return; } + "--config" => { + i += 1; + if i < args.len() && !args[i].starts_with('-') { + config_file = Some(std::path::PathBuf::from(&args[i])); + } + i += 1; + continue; + } "-r" | "--subreddit" => { i += 1; if i < args.len() && !args[i].starts_with('-') { @@ -35,9 +44,10 @@ fn main() { } } - let run_opts = if initial_subreddit.is_some() { + let run_opts = if initial_subreddit.is_some() || config_file.is_some() { Some(reddix::RunOptions { initial_subreddit, + config_file, ..Default::default() }) } else { From 2d036cc0b94332f53606911204654d39e8e7527d Mon Sep 17 00:00:00 2001 From: RoomWithOutRoof <166608075+Jah-yee@users.noreply.github.com> Date: Tue, 3 Mar 2026 10:36:43 +0800 Subject: [PATCH 3/4] feat(config): optional initial_subreddit in config UIConfig.initial_subreddit used when CLI -r not set. Document in example config. Made-with: Cursor --- docs/examples/config.yaml | 1 + src/app.rs | 4 +++- src/config.rs | 8 ++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/examples/config.yaml b/docs/examples/config.yaml index 383d892..7adb623 100644 --- a/docs/examples/config.yaml +++ b/docs/examples/config.yaml @@ -14,6 +14,7 @@ reddit: redirect_uri: "http://127.0.0.1:65010/reddix/callback" ui: theme: default + # initial_subreddit: apple # optional: open with this subreddit selected (same as -r apple) media: cache_dir: null max_size_bytes: 524288000 diff --git a/src/app.rs b/src/app.rs index 705a32b..7a56c7a 100644 --- a/src/app.rs +++ b/src/app.rs @@ -174,7 +174,9 @@ pub fn run(options: Option) -> Result<()> { session_manager: session_manager.clone(), fetch_subreddits_on_start, theme: theme::palette_for(theme), - initial_subreddit: run_opts.initial_subreddit, + initial_subreddit: run_opts + .initial_subreddit + .or_else(|| cfg.ui.initial_subreddit.clone()), }; let mut model = ui::Model::new(options); diff --git a/src/config.rs b/src/config.rs index 8c46a0c..3bac83f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -74,6 +74,9 @@ pub struct UIConfig { pub cell_width: Option, #[serde(default)] pub cell_height: Option, + /// If set, open with this subreddit selected (same as -r/--subreddit). + #[serde(default)] + pub initial_subreddit: Option, } impl Default for UIConfig { @@ -82,6 +85,7 @@ impl Default for UIConfig { theme: default_theme(), cell_width: None, cell_height: None, + initial_subreddit: None, } } } @@ -222,6 +226,9 @@ fn merge_config(mut base: Config, other: Config) -> Config { if other.ui.cell_height.is_some() { base.ui.cell_height = other.ui.cell_height; } + if other.ui.initial_subreddit.is_some() { + base.ui.initial_subreddit = other.ui.initial_subreddit; + } if other.media.cache_dir.is_some() { base.media.cache_dir = other.media.cache_dir; @@ -293,6 +300,7 @@ fn apply_env_value(cfg: &mut Config, key: &str, value: String) { cfg.ui.cell_height = Some(parsed); } } + "ui.initial_subreddit" => cfg.ui.initial_subreddit = Some(value), "media.cache_dir" => cfg.media.cache_dir = Some(PathBuf::from(value)), "media.max_size_bytes" => { if let Ok(parsed) = value.parse::() { From 8839c74dd3ce2d64cbd453140ac14c2b748c325f Mon Sep 17 00:00:00 2001 From: RoomWithOutRoof <166608075+Jah-yee@users.noreply.github.com> Date: Tue, 3 Mar 2026 10:36:50 +0800 Subject: [PATCH 4/4] docs: example config comment for save scope Made-with: Cursor --- docs/examples/config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/examples/config.yaml b/docs/examples/config.yaml index 7adb623..c71b8d2 100644 --- a/docs/examples/config.yaml +++ b/docs/examples/config.yaml @@ -11,6 +11,7 @@ reddit: - read - vote - subscribe + # - save # add this scope to use "Save post" in the action menu redirect_uri: "http://127.0.0.1:65010/reddix/callback" ui: theme: default