diff --git a/Cargo.lock b/Cargo.lock index 552c5810..8b9a428e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1031,6 +1031,12 @@ dependencies = [ "libloading", ] +[[package]] +name = "clap_lex" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + [[package]] name = "clipboard-win" version = "5.4.0" @@ -1484,6 +1490,7 @@ version = "0.1.0" dependencies = [ "bzip2", "chrono", + "clap_lex", "compio", "cosmic-mime-apps", "dirs 6.0.0", diff --git a/Cargo.toml b/Cargo.toml index 036ccfe7..6e68bdf7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,6 +54,8 @@ bzip2 = { version = "0.5", optional = true } #TODO: replace with pure Rust cra flate2 = "1.0" tar = "0.4.43" xz2 = { version = "0.1", optional = true } #TODO: replace with pure Rust crate +# CLI arguments +clap_lex = "0.7" # Internationalization i18n-embed = { version = "0.15", features = [ "fluent-system", diff --git a/src/lib.rs b/src/lib.rs index a8596d02..677799d6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,10 @@ // SPDX-License-Identifier: GPL-3.0-only use cosmic::{app::Settings, iced::Limits}; -use std::{env, fs, path::PathBuf, process}; +use std::{env, fs, path::PathBuf, process, error::Error}; + +use clap_lex::RawArgs; + use app::{App, Flags}; pub mod app; @@ -56,10 +59,10 @@ pub fn desktop() -> Result<(), Box> { localize::localize(); - let (config_handler, config) = Config::load(); + let (config_handler, config_data) = Config::load(); let mut settings = Settings::default(); - settings = settings.theme(config.app_theme.theme()); + settings = settings.theme(config_data.app_theme.theme()); settings = settings.size_limits(Limits::NONE.min_width(360.0).min_height(180.0)); settings = settings.exit_on_close(false); settings = settings.transparent(true); @@ -68,10 +71,10 @@ pub fn desktop() -> Result<(), Box> { settings = settings.no_main_window(true); } - let locations = vec![tab::Location::Desktop(desktop_dir(), String::new(), config.desktop)]; + let locations = vec![tab::Location::Desktop(desktop_dir(), String::new(), config_data.desktop)]; let flags = Flags { config_handler, - config, + config: config_data, mode: app::Mode::Desktop, locations, }; @@ -82,46 +85,61 @@ pub fn desktop() -> Result<(), Box> { /// Runs application with these settings #[rustfmt::skip] -pub fn main() -> Result<(), Box> { +pub fn main() -> Result<(), Box> { env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init(); localize::localize(); - let (config_handler, config) = Config::load(); + // Parse the arguments + let raw_args = RawArgs::from_args(); + let mut cursor = raw_args.cursor(); let mut daemonize = true; let mut locations = Vec::new(); - for arg in env::args().skip(1) { - let location = if &arg == "--no-daemon" { - daemonize = false; - continue; - } else if &arg == "--trash" { - Location::Trash - } else if &arg == "--recents" { - Location::Recents - } else if &arg == "--network" { - Location::Network("network:///".to_string(), fl!("networks")) - } else { - //TODO: support more URLs - let path = match url::Url::parse(&arg) { - Ok(url) => match url.to_file_path() { - Ok(path) => path, - Err(()) => { - log::warn!("invalid argument {:?}", arg); - continue; + + while let Some(arg) = raw_args.next_os(&mut cursor) { + match arg.to_str() { + Some("--help") | Some("-h") => { + print_help(); + process::exit(0); + } + Some("--version") | Some("-V") => { + println!( + "cosmic-files {} (git commit {})", + env!("CARGO_PKG_VERSION"), + env!("VERGEN_GIT_SHA") + ); + process::exit(0); + } + Some("--no-daemon") => { + daemonize = false; + } + Some("--trash") => locations.push(tab::Location::Trash), + Some("--recents") => locations.push(tab::Location::Recents), + Some("--network") => locations.push(tab::Location::Network("network:///".to_string(), fl!("networks"))), + Some(other) => { + // Support URLs and + + let path = match url::Url::parse(other) { + Ok(url) => match url.to_file_path() { + Ok(path) => path, + Err(()) => { + log::warn!("invalid argument {:?}", other); + continue; + } + }, + Err(_) => PathBuf::from(other), + }; + match std::fs::canonicalize(&path) { + Ok(absolute) => locations.push(tab::Location::Path(absolute)), + Err(err) => { + log::warn!("failed to canonicalize {:?}: {}", path, err); } - }, - Err(_) => PathBuf::from(arg), - }; - match fs::canonicalize(&path) { - Ok(absolute) => Location::Path(absolute), - Err(err) => { - log::warn!("failed to canonicalize {:?}: {}", path, err); - continue; } } - }; - locations.push(location); + None => { + log::warn!("Invalid argument encountered"); + } + } } if daemonize { @@ -135,9 +153,11 @@ pub fn main() -> Result<(), Box> { } } } + + let (config_handler, config_data) = Config::load(); let mut settings = Settings::default(); - settings = settings.theme(config.app_theme.theme()); + settings = settings.theme(config_data.app_theme.theme()); settings = settings.size_limits(Limits::NONE.min_width(360.0).min_height(180.0)); settings = settings.exit_on_close(false); @@ -148,7 +168,7 @@ pub fn main() -> Result<(), Box> { let flags = Flags { config_handler, - config, + config: config_data, mode: app::Mode::App, locations, }; @@ -156,3 +176,16 @@ pub fn main() -> Result<(), Box> { Ok(()) } + +fn print_help() { + println!( + r#"COSMIC Files +Designed for the COSMICâ„¢ desktop environment, cosmic-files is a libcosmic-based file manager. + +Project home page: https://github.com/pop-os/cosmic-files + +Options: + -h, --help Show this message + -v, --version Show the version of cosmic-files"# + ); +}