mod config;
mod daemon;
mod event;
mod extra;
mod logs;
mod scratchpad;
mod utils;
use crate::daemon::initialize_daemon;
use crate::extra::*;
use crate::logs::*;
use crate::utils::*;
use hyprland::error::HyprError;
use hyprland::Result;
use std::env::args;
const HYPRSCRATCH_DIR: &str = "/tmp/hyprscratch/";
const DEFAULT_LOGFILE: &str = "/tmp/hyprscratch/hyprscratch.log";
const DEFAULT_SOCKET: &str = "/tmp/hyprscratch/hyprscratch.sock";
const DEFAULT_CONFIG_FILES: [&str; 4] = [
"hypr/hyprscratch.conf",
"hyprscratch/config.conf",
"hyprscratch/hyprscratch.conf",
"hypr/hyprland.conf",
];
const KNOWN_CLI_COMMANDS: [&str; 7] = [
"get-config",
"version",
"reload",
"full",
"help",
"logs",
"kill",
];
const KNOWN_COMMANDS: [&str; 19] = [
"no-auto-reload",
"get-config",
"spotless",
"hide-all",
"kill-all",
"previous",
"version",
"reload",
"toggle",
"clean",
"eager",
"cycle",
"init",
"show",
"hide",
"menu",
"kill",
"logs",
"help",
];
fn exec_cli_command(command: &str, socket: Option<&str>, config: Option<String>) -> Result<()> {
match command {
"get-config" => print_config(socket, false),
"kill" => send_request(socket, "kill", ""),
"full" => print_full_raw(socket),
"logs" => print_logs(false),
"help" => Ok(print_help()),
"version" => Ok(println!("hyprscratch v{}", env!("CARGO_PKG_VERSION"))),
"reload" => send_request(socket, "reload", &config.unwrap_or_default()),
_ => Ok(()),
}
}
fn get_cli_command(args: &[String]) -> Option<&str> {
for arg in args {
if let Some(flag) = get_flag_name(arg) {
return Some(flag);
} else if arg.starts_with('-') {
let _ = log(format!("Unknown flag: {arg}"), Warn);
}
}
None
}
fn send_manual(args: &[String], socket: Option<&str>) -> Result<()> {
if args.len() < 3 {
let msg = format!(
"Unknown command or not enough arguments for scratchpad in '{}'",
args[1..].join(" ")
);
log(msg, Warn)?;
return Ok(());
}
send_request(socket, "manual", &args[1..].join("^"))
}
fn exec_main_command(args: &[String], config: Option<String>, socket: Option<&str>) -> Result<()> {
let get_arg = |i| args.get(i).map_or("", |x: &String| x.as_str());
let (req, msg) = (get_arg(1), get_arg(2));
match req {
"init" => initialize_daemon(args.join(" "), config, socket),
"menu" => menu(socket, msg, get_arg(3))?,
"" => print_help(),
_ if KNOWN_COMMANDS.contains(&req) => send_request(socket, req, msg)?,
_ => send_manual(args, socket)?,
}
Ok(())
}
fn resolve_command(args: &[String], config: Option<String>, socket: Option<&str>) -> Result<()> {
if let Some(cmd) = get_cli_command(args) {
exec_cli_command(cmd, socket, config)?;
return Ok(());
}
exec_main_command(args, config, socket)
}
fn hyprscratch(args: &[String]) -> Result<()> {
let depracated_features = ["summon"];
for feature in depracated_features {
if args.contains(&feature.to_string()) {
warn_deprecated(feature)?;
}
}
let config = get_flag_arg(args, "config");
let sock = get_flag_arg(args, "socket");
let socket = sock.as_deref();
resolve_command(args, config, socket)
}
fn catch_err(args: &[String], err: HyprError) {
if let HyprError::IoError(e) = err {
if e.to_string() == "Connection refused (os error 111)" {
let _ = log("Could not connect to daemon. Is it running?".into(), Warn);
}
} else {
{
let _ = log(
format!("{}, command: '{}'.", err, args[1..].join(" ")),
Warn,
);
}
}
}
fn main() {
let args: Vec<String> = args().collect();
hyprscratch(&args).unwrap_or_else(|e| catch_err(&args, e));
}