From 90e1e46fb2d56ffc7326d2fe2092b8a4c9e16958 Mon Sep 17 00:00:00 2001 From: Nabos Date: Wed, 3 Aug 2022 15:17:13 +0200 Subject: [PATCH] Reworked argument parsing --- Cargo.lock | 152 +++++++++++++++++++++++++++++++++++++----------- Cargo.toml | 8 +-- src/main.rs | 162 +++++++++++++++++++++++++--------------------------- 3 files changed, 201 insertions(+), 121 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a90468d..9cba55a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "atty" version = "0.2.14" @@ -22,6 +13,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + [[package]] name = "bitflags" version = "1.3.2" @@ -36,19 +33,55 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "clap" -version = "2.34.0" +version = "3.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "a3dbbb6653e7c55cc8595ad3e1f7be8f32aba4eb7ff7f0fd1163d4f3d137c0a9" dependencies = [ - "ansi_term", "atty", "bitflags", + "clap_derive", + "clap_lex", + "indexmap", + "once_cell", "strsim", + "termcolor", "textwrap", - "unicode-width", - "vec_map", ] +[[package]] +name = "clap_derive" +version = "3.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba52acd3b0a5c33aeada5cdaa3267cdc7c594a98731d4268cdc1532f4264cb4" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -58,6 +91,16 @@ dependencies = [ "libc", ] +[[package]] +name = "indexmap" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "itoa" version = "1.0.1" @@ -70,6 +113,42 @@ version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" +[[package]] +name = "once_cell" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" + +[[package]] +name = "os_str_bytes" +version = "6.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.37" @@ -96,18 +175,18 @@ checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "serde" -version = "1.0.136" +version = "1.0.141" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "7af873f2c95b99fcb0bd0fe622a43e29514658873c8ceba88c4cb88833a22500" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.141" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "75743a150d003dd863b51dc809bcad0d73f2102c53632f1e954e738192a3413f" dependencies = [ "proc-macro2", "quote", @@ -116,9 +195,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.79" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" dependencies = [ "itoa", "ryu", @@ -127,9 +206,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "swaysome" @@ -153,19 +232,19 @@ dependencies = [ ] [[package]] -name = "textwrap" -version = "0.11.0" +name = "termcolor" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" dependencies = [ - "unicode-width", + "winapi-util", ] [[package]] -name = "unicode-width" -version = "0.1.9" +name = "textwrap" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "unicode-xid" @@ -174,10 +253,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] -name = "vec_map" -version = "0.8.2" +name = "version_check" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "winapi" @@ -195,6 +274,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index bea0745..fec5a34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ homepage = "https://gitlab.com/hyask/swaysome" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -byteorder = "1" -serde = { version = "1", features = ["derive"] } -serde_json = "1" -clap = "2" +byteorder = "1.4.3" +clap = { version = "3.2.16", features = ["derive"] } +serde = { version = "1.0.141", features = ["derive"] } +serde_json = "1.0.82" diff --git a/src/main.rs b/src/main.rs index b27c6b8..c37e600 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ extern crate serde_json; use serde::{Deserialize, Serialize}; -use clap::{App, Arg, SubCommand, crate_version, crate_authors}; +use clap::{Args, Parser, Subcommand}; use std::env; use std::io::Cursor; use std::io::{Read, Write}; @@ -19,6 +19,53 @@ const GET_WORKSPACES: u32 = 1; // const SUBSCRIBE: u32 = 2; const GET_OUTPUTS: u32 = 3; +#[derive(Parser, Debug)] +#[clap(author, version, about = "Better multimonitor handling for sway", long_about = None)] +#[clap(propagate_version = true)] +struct Cli { + #[clap(subcommand)] + command: Command +} + +#[derive(Subcommand, Debug)] +enum Command { + #[clap(about = "Initialize the workspaces for all the outputs")] + Init(InitAction), + + #[clap(about = "Move the focused container to another workspace on the same output")] + Move(MoveAction), + + #[clap(about = "Focus to another workspace on the same output")] + Focus(FocusAction), + + #[clap(about = "Focus to another workspace on all the outputs")] + FocusAllOutputs(FocusAction), + + #[clap(about = "Move the focused container to the next output")] + NextOutput, + + #[clap(about = "Move the focused container to the previous output")] + PrevOutput, +} + +#[derive(Args, Debug)] +struct InitAction { + #[clap(value_name = "index", help = "The index to initialize with")] + name: String +} + +#[derive(Args, Debug)] +struct FocusAction { + #[clap(value_name = "index", help = "The index to focus on")] + name: String +} + +#[derive(Args, Debug)] +struct MoveAction { + #[clap(value_name = "index", help = "The index to move the container to")] + name: String +} + fn get_stream() -> UnixStream { let socket_path = match env::var("I3SOCK") { Ok(val) => val, @@ -54,7 +101,9 @@ fn send_msg(mut stream: &UnixStream, msg_type: u32, payload: &str) { let mut msg: Vec = msg_prefix[..].to_vec(); msg.extend(payload.as_bytes()); - if stream.write_all(&msg[..]).is_err() { panic!("couldn't send message"); } + if stream.write_all(&msg[..]).is_err() { + panic!("couldn't send message"); + } } fn send_command(stream: &UnixStream, command: &str) { @@ -117,7 +166,7 @@ fn get_outputs(stream: &UnixStream) -> Vec { Err(_) => panic!("Unable to get outputs"), }; let mut outputs: Vec = serde_json::from_str(&o).unwrap(); - outputs.sort_by(|x, y| x.name.cmp(&y.name)); // sort_by_key doesn't work here (https://stackoverflow.com/a/47126516) + outputs.sort_by(|x, y| x.name.cmp(&y.name)); // sort_by_key doesn't work here (https://stackoverflow.com/a/47126516) outputs } @@ -142,10 +191,7 @@ fn get_workspaces(stream: &UnixStream) -> Vec { fn get_current_output_index(stream: &UnixStream) -> String { let outputs = get_outputs(stream); - let focused_output_index = match outputs - .iter() - .position(|x| x.focused) - { + let focused_output_index = match outputs.iter().position(|x| x.focused) { Some(i) => i, None => panic!("WTF! No focused output???"), }; @@ -156,10 +202,7 @@ fn get_current_output_index(stream: &UnixStream) -> String { fn get_current_output_name(stream: &UnixStream) -> String { let outputs = get_outputs(stream); - let focused_output_index = match outputs - .iter() - .find(|x| x.focused) - { + let focused_output_index = match outputs.iter().find(|x| x.focused) { Some(i) => i.name.as_str(), None => panic!("WTF! No focused output???"), }; @@ -214,15 +257,12 @@ fn move_container_to_prev_output(stream: &UnixStream) { fn move_container_to_next_or_prev_output(stream: &UnixStream, go_to_prev: bool) { let outputs = get_outputs(stream); - let focused_output_index = match outputs - .iter() - .position(|x| x.focused) - { + let focused_output_index = match outputs.iter().position(|x| x.focused) { Some(i) => i, None => panic!("WTF! No focused output???"), }; - let target_output = if go_to_prev { + let target_output = if go_to_prev { &outputs[(focused_output_index + outputs.len() - 1) % outputs.len()] } else { &outputs[(focused_output_index + 1) % outputs.len()] @@ -231,9 +271,7 @@ fn move_container_to_next_or_prev_output(stream: &UnixStream, go_to_prev: bool) let workspaces = get_workspaces(stream); let target_workspace = workspaces .iter() - .find(|x| { - x.output == target_output.name && x.visible - }) + .find(|x| x.output == target_output.name && x.visible) .unwrap(); // Move container to target workspace @@ -260,73 +298,27 @@ fn init_workspaces(stream: &UnixStream, workspace_name: &String) { } fn main() { - let matches = App::new("swaysome") - .version(crate_version!()) - .author(crate_authors!()) - .about("Better multimonitor handling for sway") - .subcommand( - SubCommand::with_name("init") - .about("Initialize the workspaces for all the outputs") - .arg( - Arg::with_name("index") - .help("The index to initialize with") - .required(true) - .takes_value(true), - ), - ) - .subcommand( - SubCommand::with_name("focus") - .about("Focus to another workspace on the same output") - .arg( - Arg::with_name("index") - .help("The index to focus on") - .required(true) - .takes_value(true), - ), - ) - .subcommand( - SubCommand::with_name("focus_all_outputs") - .about("Focus to another workspace on all the outputs") - .arg( - Arg::with_name("index") - .help("The index to focus on") - .required(true) - .takes_value(true), - ), - ) - .subcommand( - SubCommand::with_name("move") - .about("Move the focused container to another workspace on the same output") - .arg( - Arg::with_name("index") - .help("The index to move the container to") - .required(true) - .takes_value(true), - ), - ) - .subcommand( - SubCommand::with_name("next_output") - .about("Move the focused container to the next output"), - ) - .subcommand( - SubCommand::with_name("prev_output") - .about("Move the focused container to the previous output"), - ) - .get_matches(); - + let cli = Cli::parse(); let stream = get_stream(); - if let Some(matches) = matches.subcommand_matches("init") { - init_workspaces(&stream, &matches.value_of("index").unwrap().to_string()); - } else if let Some(matches) = matches.subcommand_matches("move") { - move_container_to_workspace(&stream, &matches.value_of("index").unwrap().to_string()); - } else if let Some(matches) = matches.subcommand_matches("focus") { - focus_to_workspace(&stream, &matches.value_of("index").unwrap().to_string()); - } else if let Some(matches) = matches.subcommand_matches("focus_all_outputs") { - focus_all_outputs_to_workspace(&stream, &matches.value_of("index").unwrap().to_string()); - } else if matches.subcommand_matches("next_output").is_some() { - move_container_to_next_output(&stream); - } else if matches.subcommand_matches("prev_output").is_some() { - move_container_to_prev_output(&stream); + match &cli.command { + Command::Init(action) => { + init_workspaces(&stream, &action.name); + } + Command::Move(action) => { + move_container_to_workspace(&stream, &action.name); + } + Command::Focus(action) => { + focus_to_workspace(&stream, &action.name); + } + Command::FocusAllOutputs(action) => { + focus_all_outputs_to_workspace(&stream, &action.name); + } + Command::NextOutput => { + move_container_to_next_output(&stream); + } + Command::PrevOutput => { + move_container_to_prev_output(&stream); + } } }