use std::{str::FromStr, string::FromUtf8Error}; use log::debug; use thiserror::Error; use crate::{ hlwm::{ command::{CommandError, HlwmCommand}, key::{KeyParseError, Keybind}, Client, }, split, }; #[derive(Clone, Debug, Error)] pub enum EnvironError { #[error("keybind parsing error: [{0}]")] KeyParseError(#[from] KeyParseError), #[error("command execution error: [{0}]")] CommandError(#[from] CommandError), } impl From for EnvironError { fn from(value: FromUtf8Error) -> Self { CommandError::UtfError(value).into() } } pub enum ActiveKeybinds { All, OmitNamedTagBinds, OnlyNamedTagBinds, } pub fn active_keybinds(ty: ActiveKeybinds) -> Result, EnvironError> { let (use_tag, move_tag) = ( HlwmCommand::UseTag(String::new()).to_string(), HlwmCommand::MoveTag(String::new()).to_string(), ); String::from_utf8(Client::new().execute(HlwmCommand::ListKeybinds)?.stdout)? .split("\n") .map(|l| l.trim()) .filter(|l| !l.is_empty()) .filter(|i| { let parts = split::tab_or_space(*i); if parts.len() < 2 { debug!( "active_keybinds: parts.len() for [{i}] was [{}]; expected >= 2", parts.len() ); return false; } let command = parts[1].as_str(); match ty { ActiveKeybinds::All => true, ActiveKeybinds::OmitNamedTagBinds => command != use_tag && command != move_tag, ActiveKeybinds::OnlyNamedTagBinds => command == use_tag || command == move_tag, } }) .map(|row: &str| { Ok(Keybind::from_str(row).map_err(|err| { debug!("row: [{row}], error: [{err}]"); err })?) }) .collect::, EnvironError>>() }