From 60a31fd43c90d0513cc5e9a6d8494cc4def34179 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Fri, 8 Aug 2025 16:10:46 -0700 Subject: [PATCH] add CLI for pre-populating text or files to send --- Cargo.lock | 117 ++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 1 + src/app/mod.rs | 12 +++++ src/cli.rs | 15 +++++++ src/main.rs | 39 +++++++++++++++++ 5 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 src/cli.rs diff --git a/Cargo.lock b/Cargo.lock index 73eb95b..a91c63d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,6 +47,56 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +dependencies = [ + "windows-sys 0.60.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.60.2", +] + [[package]] name = "arc-swap" version = "1.7.1" @@ -345,6 +395,46 @@ dependencies = [ "libloading", ] +[[package]] +name = "clap" +version = "4.5.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50fd97c9dc2399518aa331917ac6f274280ec5eb34e555dd291899745c48ec6f" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c35b5830294e1fa0462034af85cc95225a4cb07092c088c55bda3147cfcd8f65" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "clap_lex" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + [[package]] name = "cmake" version = "0.1.54" @@ -354,6 +444,12 @@ dependencies = [ "cc", ] +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + [[package]] name = "compact_str" version = "0.8.1" @@ -1186,6 +1282,12 @@ dependencies = [ "serde", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.12.1" @@ -1227,6 +1329,7 @@ dependencies = [ "axum", "axum-server", "chrono", + "clap", "crossterm", "directories", "figment", @@ -1300,7 +1403,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.53.3", ] [[package]] @@ -1518,6 +1621,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + [[package]] name = "openssl" version = "0.10.73" @@ -2680,6 +2789,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "vcpkg" version = "0.2.15" diff --git a/Cargo.toml b/Cargo.toml index ca09713..9e79665 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" axum = { version = "0.8", features = ["macros"] } axum-server = { version = "0.7", features = ["tls-rustls", "tokio-rustls"] } chrono = "0.4" +clap = { version = "4.5.43", features = ["derive"] } crossterm = { version = "0.28", features = ["event-stream"] } directories = "6" figment = { version = "0.10", features = ["toml", "test", "env"] } diff --git a/src/app/mod.rs b/src/app/mod.rs index b1b7fba..4f21a36 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -105,6 +105,18 @@ impl App { Ok(()) } + pub fn input(&mut self) -> &mut Input { + &mut self.input + } + + pub fn files(&mut self) -> &mut FileExplorer { + &mut self.file_picker + } + + pub fn text(&mut self) -> &mut Option { + &mut self.text + } + pub fn screen(&self) -> CurrentScreen { *self.screen.last().unwrap() } diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 0000000..564eaf7 --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,15 @@ +use std::ffi::OsString; + +use clap::Parser; + +#[derive(Debug, Parser)] +#[clap(author, version, about)] +pub struct Cli { + /// File to pre-select for sending. + #[clap(long, short)] + pub file: Option, + + /// Text string to send. + #[clap(long, short)] + pub text: Option, +} diff --git a/src/main.rs b/src/main.rs index 06c2cfe..f8049d7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,23 @@ +use std::{path::Path, str::FromStr}; + +use clap::Parser; use jocalsend::{Config, JocalService, Listeners, error::Result}; use log::{error, info}; use ratatui::DefaultTerminal; +use ratatui_explorer::FileExplorer; use tokio::{sync::mpsc::unbounded_channel, task::JoinSet}; use tui_logger::{LevelFilter, init_logger, set_env_filter_from_env}; mod app; use app::{App, CurrentScreen, Peer}; +mod cli; +use cli::Cli; + fn main() -> Result<()> { + // just in case we need to display the help + let _ = Cli::parse(); + if std::env::var("RUST_LOG").is_err() { unsafe { std::env::set_var("RUST_LOG", "jocalsend"); @@ -35,6 +45,18 @@ async fn start_and_run(terminal: &mut DefaultTerminal, config: Config) -> Result let mut app = App::new(service, event_listener); + let cli = Cli::parse(); + if let Some(text) = cli.text { + let i = app.input(); + *i = i.clone().with_value(text.clone()); + app.text().replace(text); + } + if let Some(file) = cli.file { + let path = std::path::PathBuf::from_str(&file.to_string_lossy()) + .unwrap_or_else(|_| panic!("Could not create path from {file:?}")); + set_file_selection(&path, app.files()); + } + let mut handles = JoinSet::new(); app.service.start(&mut handles).await; loop { @@ -97,3 +119,20 @@ async fn shutdown(handles: &mut JoinSet) { } } } + +fn set_file_selection(path: &Path, explorer: &mut FileExplorer) { + if path.is_absolute() { + let parent = path.parent().map(|f| f.to_path_buf()).unwrap_or("/".into()); + let _ = explorer.set_cwd(parent); + } else { + let parent = path.parent().map(|f| f.to_path_buf()).unwrap_or("/".into()); + let _ = explorer.set_cwd(parent); + }; + let files = explorer.files().clone(); + for (i, f) in files.iter().enumerate() { + if f.name() == path.file_name().unwrap().to_string_lossy() { + explorer.set_selected_idx(i); + break; + } + } +}