82 lines
2.1 KiB
Rust
82 lines
2.1 KiB
Rust
use clap::Subcommand;
|
|
use rustyline::{error::ReadlineError, DefaultEditor};
|
|
use thiserror::Error;
|
|
|
|
use crate::hlwm::{
|
|
command::{CommandParseError, HlwmCommand},
|
|
key::Key,
|
|
parser::{FromCommandArgs, ParseError},
|
|
};
|
|
|
|
#[derive(Subcommand, Debug, Clone)]
|
|
pub enum Add {
|
|
/// Add a new keybind to the existing hlctl config
|
|
#[clap(arg_required_else_help = true)]
|
|
Keybind {
|
|
#[arg(short, long)]
|
|
interactive: bool,
|
|
},
|
|
}
|
|
|
|
#[derive(Debug, Clone, Error)]
|
|
pub enum Error {
|
|
#[error("readline error: [{0}]")]
|
|
ReadlineError(String),
|
|
#[error("parse error: [{0}]")]
|
|
KeyParseError(#[from] ParseError),
|
|
#[error("could not parse command: [{0}]")]
|
|
CommandParseError(#[from] CommandParseError),
|
|
}
|
|
|
|
impl From<ReadlineError> for Error {
|
|
fn from(value: ReadlineError) -> Self {
|
|
Self::ReadlineError(value.to_string())
|
|
}
|
|
}
|
|
|
|
impl Add {
|
|
pub fn run(self) -> Result<(), Error> {
|
|
match self {
|
|
Add::Keybind { interactive } => {
|
|
if interactive {
|
|
keybind_interactive()
|
|
} else {
|
|
todo!()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn keybind_interactive() -> Result<(), Error> {
|
|
let mut read = DefaultEditor::new()?;
|
|
let keys = read
|
|
.readline("Keys (Separated by spaces, tabs, +, or -): ")?
|
|
.trim()
|
|
.split([' ', '\t', '+', '-'])
|
|
.map(|l| l.trim())
|
|
.filter(|l| !l.is_empty())
|
|
.map(|k| Key::from_str_case_insensitive(k))
|
|
.collect::<Result<Vec<_>, _>>()?;
|
|
|
|
let command = {
|
|
let read = read.readline("Command (Arguments separated by tabs or spaces): ")?;
|
|
let mut args = read
|
|
.trim()
|
|
.split([' ', '\t'])
|
|
.map(|a| a.trim())
|
|
.filter(|a| !a.is_empty())
|
|
.map(|a| a.to_string());
|
|
match args.next() {
|
|
Some(cmd) => HlwmCommand::from_command_args(&cmd, args)?,
|
|
None => {
|
|
println!("No command provided");
|
|
std::process::exit(1);
|
|
}
|
|
}
|
|
};
|
|
|
|
println!("{keys:?} -> {command:?}");
|
|
Ok(())
|
|
}
|