2022-07-06 22:11:41 -04:00

108 lines
3.5 KiB
Rust

// Enable clippy 'hard mode'
#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
// Intended behavior (10_f64 as i32)
#![allow(clippy::cast_possible_truncation)]
// Cannot be fixed
#![allow(clippy::multiple_crate_versions)]
#![allow(clippy::struct_excessive_bools)]
// TODO: Remove
#![allow(dead_code, unused_imports)]
mod box_;
mod errors;
mod math_eval;
mod set;
mod shuf;
mod sort;
mod stdin;
mod trim;
mod uniq;
mod utils;
// mod xargs;
use clap::{Parser, Subcommand};
use kakplugin::{display_message, get_var, KakError};
use std::env;
use strum::VariantNames;
#[derive(Parser, Debug)]
#[clap(about, version, author)]
struct Cli {
#[clap(subcommand)]
command: Commands,
// TODO: Allow clap to parse these. Currently clap treats them as positional
// #[clap(env = "kak_command_fifo", takes_value = false)]
// kak_command_fifo_name: PathBuf,
// #[clap(env = "kak_response_fifo", takes_value = false)]
// kak_response_fifo_name: PathBuf,
}
#[derive(Subcommand, Debug, strum::EnumVariantNames)]
#[strum(serialize_all = "kebab_case")]
enum Commands {
#[clap(about = "Sorts selections based on content or content regex match")]
Sort(sort::Options),
#[clap(about = "Shuffle selections")]
Shuf(shuf::Options),
#[clap(about = "Find unique selections based on optional regex match")]
Uniq(uniq::Options),
#[clap(about = "Evaluate selections as a math expression", visible_aliases = &["bc", "eval"])]
MathEval(math_eval::Options),
#[clap(about = "Trim every selection")]
Trim(trim::Options),
#[clap(about = "Perform set operations on selections")]
Set(set::Options),
// #[clap(about = "")]
// Xargs(xargs::Options),
#[clap(about = "Pass each selection null terminated to a command")]
Stdin(stdin::Options),
#[clap(about = "Make boxes out of selections", visible_aliases = &["square"])]
Box_(box_::Options),
}
fn main() {
// First, check if we are just getting candidates to run the program. kak_command_fifo is not needed for this
let args = env::args().collect::<Vec<_>>();
if args.len() == 2 && args[1] == "shell-script-candidates" {
match kakplugin::generate_shell_script_candidates(Commands::VARIANTS) {
Err(e) => eprintln!("{e:?}"),
Ok(()) => {}
}
return;
}
if get_var("kak_command_fifo")
.and(get_var("kak_response_fifo"))
.is_err()
{
panic!("Environment variable kak_command_fifo and kak_response_fifo must be set");
}
let (msg, msg_details) = match run() {
Ok(msg) => (msg, None),
Err(e) => (e.to_string(), Some(e.details())),
};
if let Err(display_error) = display_message(&msg, msg_details.as_ref()) {
// If there was an error sending the display message to kakoune, print it out
eprintln!(
"Error sending message '{msg:?}' (details: '{msg_details:?}') to kak: {display_error:?}"
);
}
}
fn run() -> Result<String, KakError> {
let options = Cli::try_parse().map_err(|e| KakError::Custom(format!("{e}")))?;
match &options.command {
Commands::Sort(o) => sort::sort(o),
Commands::Shuf(o) => shuf::shuf(o),
Commands::Uniq(o) => uniq::uniq(o),
Commands::MathEval(o) => math_eval::math_eval(o),
Commands::Trim(o) => trim::trim(o),
Commands::Set(o) => set::set(o),
// Commands::Xargs(o) => xargs::xargs(o),
Commands::Stdin(o) => stdin::stdin(o),
Commands::Box_(o) => box_::box_(o),
}
}