aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs85
1 files changed, 59 insertions, 26 deletions
diff --git a/src/main.rs b/src/main.rs
index 280afb1..3c35738 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,36 +1,68 @@
use swayipc::{Connection, WindowChange, EventType};
-use std::{env,fs::File, io::Read};
+use std::{env,fs::File, io::{Read, self}, num, fmt::Display};
use regex::Regex;
struct WindowHider {
- term: String
+ term: String,
+ regex: Regex,
+}
+
+enum Error {
+ IoError(io::Error),
+ ParseIntError(num::ParseIntError),
+ RegexParseError(i32),
+ SwayIpcError(swayipc::Error)
+}
+
+impl From<io::Error> for Error {
+ fn from(value: io::Error) -> Self {
+ Self::IoError(value)
+ }
+}
+
+impl From<num::ParseIntError> for Error {
+ fn from(value: num::ParseIntError) -> Self {
+ Self::ParseIntError(value)
+ }
+}
+
+impl From<swayipc::Error> for Error {
+ fn from(value: swayipc::Error) -> Self {
+ Self::SwayIpcError(value)
+ }
+}
+
+impl Display for Error {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Error::IoError(err) => err.fmt(f),
+ Error::ParseIntError(err) => err.fmt(f),
+ Error::SwayIpcError(err) => err.fmt(f),
+ Error::RegexParseError(pid) => write!(f, "Failed to regex match for pid {pid}"),
+ }
+ }
}
impl WindowHider {
- fn get_parent_term_pid(&self, pid: i32, is_root: bool) -> Option<i32> {
- let mut file = String::new();
- File::open(format!("/proc/{pid}/stat")).expect("procfs stat doesn't exist").read_to_string(&mut file).unwrap();
- let re = Regex::new(r"\d+ \((.*)\) (\w) (\d+) \d+").unwrap().captures(&file).unwrap();
- let name = re.get(1).unwrap().as_str();
- let status = re.get(2).unwrap().as_str();
- let ppid = re.get(3).unwrap().as_str().parse::<i32>().unwrap();
-
- println!("looking for {pid}. {name}, {status}, {ppid}");
+ fn get_parent_term_pid(&self, pid: i32, is_root: bool) -> Result<Option<i32>, Error> {
+ let mut buf = String::new();
+ File::open(format!("/proc/{pid}/stat"))?.read_to_string(&mut buf)?;
+
+ let Some((_, [name, ppid])) = self.regex.captures(&buf).map(|caps| caps.extract()) else {
+ return Err(Error::RegexParseError(pid));
+ };
+
+ let ppid = ppid.parse::<i32>()?;
+
match name {
- _ if name == self.term && !is_root => {
- Some(pid)
- },
- _ if name == "init" => {
- None
- }
- _ => {
- self.get_parent_term_pid(ppid, false)
- }
+ "init" => Ok(None),
+ _ if name == self.term && !is_root => Ok(Some(pid)),
+ _ => self.get_parent_term_pid(ppid, false)
}
}
- fn hide(&self, conn: &mut Connection, pid: i32) -> Result<(), swayipc::Error> {
- let ppid = self.get_parent_term_pid(pid, true);
+ fn hide(&self, conn: &mut Connection, pid: i32) -> Result<(), Error> {
+ let ppid = self.get_parent_term_pid(pid, true)?;
if let Some(ppid) = ppid {
println!("found parent pid of {pid} as {ppid}");
conn.run_command(format!("[pid={ppid}] mark --add {pid}, move scratchpad"))?;
@@ -38,7 +70,7 @@ impl WindowHider {
Ok(())
}
- fn show(&self, conn: &mut Connection, pid: i32) -> Result<(), swayipc::Error> {
+ fn show(&self, conn: &mut Connection, pid: i32) -> Result<(), Error> {
conn.run_command(format!("[con_mark={pid}] move workspace current"))?;
conn.run_command(format!("[con_mark={pid}] floating toggle"))?;
Ok(())
@@ -59,7 +91,8 @@ fn main() -> Result<(), swayipc::Error> {
}
let wh = WindowHider {
- term: args.remove(1)
+ term: args.remove(1),
+ regex: Regex::new(r"\d+ \((.*)\) \w (\d+) \d+").unwrap()
};
for item in evs {
@@ -70,14 +103,14 @@ fn main() -> Result<(), swayipc::Error> {
if let Some(pid) = win.container.pid {
match wh.hide(&mut conn, pid) {
Ok(_) => {},
- Err(_) => println!("failed to hide terminal {pid}")
+ Err(err) => eprintln!("failed to hide terminal {pid}: {err}")
};
}
} else if win.change == WindowChange::Close {
if let Some(pid) = win.container.pid {
match wh.show(&mut conn, pid) {
Ok(_) => {},
- Err(_) => println!("failed to show terminal {pid}")
+ Err(err) => eprintln!("failed to show terminal {pid}: {err}")
};
}
}