Browse Source

Rewrite using clap.

Kestrel 3 tháng trước cách đây
mục cha
commit
b0d879bd7f
5 tập tin đã thay đổi với 83 bổ sung79 xóa
  1. 1 0
      .gitignore
  2. 2 1
      Cargo.toml
  3. 10 10
      src/act.rs
  4. 68 64
      src/main.rs
  5. 2 4
      src/sway.rs

+ 1 - 0
.gitignore

@@ -1 +1,2 @@
 /target
+.*.sw?

+ 2 - 1
Cargo.toml

@@ -1,5 +1,5 @@
 [package]
-name = "swaykey"
+name = "swaynav"
 version = "0.1.0"
 edition = "2021"
 
@@ -8,3 +8,4 @@ edition = "2021"
 [dependencies]
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
+clap = { version = "4.5", features = ["derive", "env"] }

+ 10 - 10
src/act.rs

@@ -12,14 +12,14 @@ pub struct SwayKeyStore {
 
 impl SwayKeyStore {
     pub fn load() -> Self {
-        let f = File::open(format!("{}/swaykey.json", std::env::var("XDG_RUNTIME_DIR").unwrap()));
+        let f = File::open(format!("{}/swaynav.json", std::env::var("XDG_RUNTIME_DIR").unwrap()));
 
         if f.is_err() { return Self::default() }
 
-        serde_json::from_reader(f.unwrap()).expect("valid JSON in swaykey temp storage")
+        serde_json::from_reader(f.unwrap()).expect("valid JSON in swaynav temp storage")
     }
     pub fn save(&self) {
-        let f = File::create(format!("{}/swaykey.json", std::env::var("XDG_RUNTIME_DIR").unwrap()));
+        let f = File::create(format!("{}/swaynav.json", std::env::var("XDG_RUNTIME_DIR").unwrap()));
 
         serde_json::to_writer(f.unwrap(), self).expect("Successful serialization")
     }
@@ -40,7 +40,7 @@ fn update_act_map(key: &ActivityWorkspace) {
 
 #[derive(Clone)]
 pub struct ActivityWorkspace {
-    pub index: i32,
+    pub index: usize,
     pub group: Option<String>
 }
 
@@ -69,12 +69,12 @@ impl ActivityWorkspace {
             })
     }
 
-    pub fn set_index(&mut self, index: i32) {
+    pub fn set_index(&mut self, index: usize) {
         self.index = index;
     }
 
-    pub fn shift_index(&mut self, by: i32) {
-        self.index = ((self.index - 1 + by + 10) % 10) + 1;
+    pub fn shift_index(&mut self, by: isize) {
+        self.index = ((self.index + 9).wrapping_add_signed(by) % 10) + 1;
     }
 }
 
@@ -103,21 +103,21 @@ impl<'a> Activity<'a> {
         self.active.borrow().group.clone()
     }
 
-    pub fn shift_ws(&self, by: i32) {
+    pub fn shift_ws(&self, by: isize) {
         self.active.borrow_mut().shift_index(by);
         self.si.switch_to_workspace(self.active.borrow().to_string().as_str()).unwrap();
 
         update_act_map(&self.active.borrow());
     }
 
-    pub fn set_ws(&self, to: i32) {
+    pub fn set_ws(&self, to: usize) {
         self.active.borrow_mut().set_index(to);
         self.si.switch_to_workspace(self.active.borrow().to_string().as_str()).unwrap();
 
         update_act_map(&self.active.borrow());
     }
 
-    pub fn move_to_ws(&self, to: i32) {
+    pub fn move_to_ws(&self, to: usize) {
         let mut k = self.active.borrow().clone();
         k.set_index(to);
         self.si.move_to_workspace(k.to_string().as_str()).unwrap();

+ 68 - 64
src/main.rs

@@ -1,77 +1,81 @@
-use std::collections::HashMap;
 use std::collections::HashSet;
 
+use clap::Parser;
+
 mod sway;
 mod act;
 
-fn main() {
-    let mut cmd = std::env::args().skip(1);
-
-    let verb = cmd.next();
-    let noun = cmd.next();
-
-    let si = sway::SwayInterface::new();
-
-    let act = act::Activity::current(&si);
-
-    let mut cmds : HashMap<&'static str, Box<dyn Fn(Option<String>) -> ()>> = HashMap::new();
-
-    cmds.insert("ws_left", Box::new(|_| {
-        act.shift_ws(-1)
-    }));
-
-    cmds.insert("ws_right", Box::new(|_| {
-        act.shift_ws(1)
-    }));
-
-    cmds.insert("ws_set", Box::new(|index| {
-        let ind : Option<i32> = index.unwrap().parse().ok();
-        if ind.is_some() {
-            act.set_ws(ind.unwrap())
-        }
-    }));
+#[derive(clap::Parser)]
+struct Swaynav {
+    #[arg(env = "SWAYSOCK")]
+    swaysock: String,
 
-    cmds.insert("move_to_ws", Box::new(|index| {
-        let ind : Option<i32> = index.unwrap().parse().ok();
-        if ind.is_some() {
-            act.move_to_ws(ind.unwrap())
-        }
-    }));
-
-    cmds.insert("act_list", Box::new(|_| {
-        let uniques : HashSet<Option<String>> = si.get_workspaces().unwrap().iter().map(|ws| act::ActivityWorkspace::from_string(&ws.name).group).collect();
-        for u in uniques {
-            println!("{}", if u.is_some() { u.unwrap() } else { "default".to_string() });
-        }
-    }));
-
-    cmds.insert("act_change", Box::new(|to| {
-        let nact = act::Activity::by_name(&si, &to.unwrap());
-        nact.shift_ws(0);
-    }));
-
-    cmds.insert("act_restore", Box::new(|_| {
-        let mut store = act::SwayKeyStore::load();
-        let lact = store.last_act.as_deref().unwrap_or_else(|| "default");
+    #[command(subcommand)]
+    cmd: SwaynavCommands
+}
 
-        let nact = act::Activity::by_name(&si, lact);
-        nact.shift_ws(0);
+#[derive(clap::Subcommand)]
+enum SwaynavCommands {
+    /// Move one workspace left
+    WsLeft,
+    /// Move one workspace right
+    WsRight,
+    /// Set active workspace
+    WsSet { new_ws: usize },
+    /// Move active container to workspace
+    MoveToWs { ws: usize },
+    /// List current activities
+    ActList,
+    /// Change active activity
+    ActChange { new_act: String },
+    /// Restore to last active activity
+    ActRestore,
+}
 
-        store.last_act = act.group();
-        store.save();
-    }));
+fn main() {
+    let args = Swaynav::parse();
 
-    if verb == None {
-        println!("Need a verb!");
-        return
-    }
+    let si = sway::SwayInterface::new(&args.swaysock);
 
-    let cmd = cmds.get(verb.as_ref().unwrap().as_str());
+    let act = act::Activity::current(&si);
 
-    if cmd.is_none() {
-        println!("Unknown verb {}", verb.unwrap());
-    }
-    else {
-        (cmd.unwrap())(noun)
+    match args.cmd {
+        SwaynavCommands::WsLeft => {
+            act.shift_ws(-1)
+        },
+        SwaynavCommands::WsRight => {
+            act.shift_ws(1)
+        },
+        SwaynavCommands::WsSet { new_ws } => {
+            act.set_ws(new_ws)
+        },
+        SwaynavCommands::MoveToWs { ws } => {
+            act.move_to_ws(ws)
+        },
+        SwaynavCommands::ActList => {
+            let uniques : HashSet<Option<String>> = si.get_workspaces().unwrap_or(vec![]).iter().map(|ws| act::ActivityWorkspace::from_string(&ws.name).group).collect();
+            for u in uniques {
+                println!("{}", if u.is_some() { u.unwrap() } else { "default".to_string() });
+            }
+        },
+        SwaynavCommands::ActChange { new_act } => {
+            let mut store = act::SwayKeyStore::load();
+
+            let nact = act::Activity::by_name(&si, &new_act);
+            nact.shift_ws(0);
+
+            store.last_act = act.group();
+            store.save();
+        },
+        SwaynavCommands::ActRestore => {
+            let mut store = act::SwayKeyStore::load();
+            let lact = store.last_act.as_deref().unwrap_or_else(|| "default");
+
+            let nact = act::Activity::by_name(&si, lact);
+            nact.shift_ws(0);
+
+            store.last_act = act.group();
+            store.save();
+        },
     }
 }

+ 2 - 4
src/sway.rs

@@ -1,7 +1,6 @@
 use std::io::prelude::*;
 use std::os::unix::net::UnixStream;
 use std::cell::RefCell;
-use std::convert::AsMut;
 use serde::Deserialize;
 
 fn into_array<A, T>(slice: &[T]) -> A
@@ -70,9 +69,7 @@ pub struct SwayInterface {
 }
 
 impl SwayInterface {
-    pub fn new() -> Self {
-        let path = std::env::var("SWAYSOCK").expect("SWAYSOCK to be set");
-
+    pub fn new(path: &str) -> Self {
         let sock = UnixStream::connect(path).expect("Can connect to sway socket");
 
         SwayInterface { sock: RefCell::new(sock) }
@@ -132,6 +129,7 @@ impl SwayInterface {
 
 #[derive(Deserialize)]
 pub struct Workspace {
+    #[allow(unused)]
     id: u32,
     pub name: String,
     focused: bool