Make sort a subcommand

This commit is contained in:
Austen Adler 2022-02-12 22:50:30 -05:00
parent cd566d1708
commit b0e90f63b6
2 changed files with 48 additions and 29 deletions

View File

@ -41,18 +41,14 @@ define-command sort-selections -params 0.. %{
reg dquote %val{selections} reg dquote %val{selections}
eval %sh{ eval %sh{
regex="${1:-.*}" regex="${1:-.*}"
# use kak_command_fifo kak_response_fifo;
# TODO: Use a comand fifo to read/write selections ~/syncthing/code/kakutils-rs/target/debug/kakutils-rs sort "$regex" -- "$@"
eval set -- "$kak_quoted_selections"
# TODO: Send additional parameters
rust-selection-sort -R "$regex" -f "$kak_command_fifo" -- "$@"
} }
exec R exec R
} }
} }
---- ----
== Usage == Usage

View File

@ -3,6 +3,7 @@
mod errors; mod errors;
use alphanumeric_sort::compare_str; use alphanumeric_sort::compare_str;
use clap::Parser; use clap::Parser;
use clap::Subcommand;
use errors::KakMessage; use errors::KakMessage;
use regex::Regex; use regex::Regex;
use std::env; use std::env;
@ -13,16 +14,28 @@ use std::io::Write;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[clap(about, version, author)] #[clap(about, version, author)]
struct Options { struct Cli {
#[clap(subcommand)]
command: Commands,
// TODO: Allow clap to parse these. Currently clap treats them as positional // TODO: Allow clap to parse these. Currently clap treats them as positional
// #[clap(env = "kak_command_fifo", takes_value = false)] // #[clap(env = "kak_command_fifo", takes_value = false)]
// kak_command_fifo_name: PathBuf, // kak_command_fifo_name: PathBuf,
// #[clap(env = "kak_response_fifo", takes_value = false)] // #[clap(env = "kak_response_fifo", takes_value = false)]
// kak_response_fifo_name: PathBuf, // kak_response_fifo_name: PathBuf,
}
#[derive(Subcommand, Debug)]
enum Commands {
// #[clap(flatten)]
Sort(SortOptions),
}
#[derive(clap::StructOpt, Debug)]
struct SortOptions {
#[clap(index = 1)] #[clap(index = 1)]
regex: Option<String>, regex: Option<String>,
#[clap(short = 'S', long)]
// TODO: Can we invert a boolean? This name is terrible // TODO: Can we invert a boolean? This name is terrible
#[clap(short = 'S', long)]
no_skip_whitespace: bool, no_skip_whitespace: bool,
#[clap(short, long)] #[clap(short, long)]
lexicographic_sort: bool, lexicographic_sort: bool,
@ -39,32 +52,42 @@ fn main() {
} }
}; };
send_message(&msg); if let Err(e) = send_message(&msg) {
println!("{:?}", e);
}
} }
fn send_message(msg: &KakMessage) { fn send_message(msg: &KakMessage) -> Result<(), Box<dyn std::error::Error>> {
let msg_str = msg.0.replace('\'', "''"); let msg_str = msg.0.replace('\'', "''");
{ {
let mut f = open_command_fifo().unwrap(); let mut f =
open_command_fifo().map_err(|e| format!("Could not open command fifo: {:?}", e))?;
write!(f, "echo '{}';", msg_str).unwrap(); write!(f, "echo '{}';", msg_str)?;
write!(f, "echo -debug '{}';", msg_str).unwrap(); write!(f, "echo -debug '{}';", msg_str)?;
if let Some(debug_msg_str) = &msg.1 { if let Some(debug_msg_str) = &msg.1 {
write!(f, "echo -debug '{}';", debug_msg_str.replace('\'', "''")).unwrap(); write!(f, "echo -debug '{}';", debug_msg_str.replace('\'', "''"))?;
} }
} }
Ok(())
} }
fn run() -> Result<KakMessage, KakMessage> { fn run() -> Result<KakMessage, KakMessage> {
let options = Options::try_parse().map_err(|e| { let options = Cli::try_parse().map_err(|e| {
KakMessage( KakMessage(
"Error parsing arguments".to_string(), "Error parsing arguments".to_string(),
Some(format!("Could not parse: {:?}", e)), Some(format!("Could not parse: {:?}", e)),
) )
})?; })?;
let re = options match &options.command {
Commands::Sort(sort_options) => sort(sort_options),
}
}
fn sort(sort_options: &SortOptions) -> Result<KakMessage, KakMessage> {
let re = sort_options
.regex .regex
.as_ref() .as_ref()
.map(|r| Regex::new(r)) .map(|r| Regex::new(r))
@ -72,7 +95,7 @@ fn run() -> Result<KakMessage, KakMessage> {
.map_err(|_| { .map_err(|_| {
format!( format!(
"Invalid regular expression: {}", "Invalid regular expression: {}",
options.regex.unwrap_or("".to_string()) sort_options.regex.as_ref().unwrap_or(&"".to_string())
) )
})?; })?;
@ -84,7 +107,7 @@ fn run() -> Result<KakMessage, KakMessage> {
selections selections
.iter() .iter()
.map(|a| { .map(|a| {
if options.no_skip_whitespace { if sort_options.no_skip_whitespace {
a a
} else { } else {
a.trim() a.trim()
@ -104,7 +127,7 @@ fn run() -> Result<KakMessage, KakMessage> {
let a = a_key.unwrap_or(a); let a = a_key.unwrap_or(a);
let b = b_key.unwrap_or(b); let b = b_key.unwrap_or(b);
if options.lexicographic_sort { if sort_options.lexicographic_sort {
a.cmp(b) a.cmp(b)
} else { } else {
compare_str(a, b) compare_str(a, b)
@ -115,7 +138,7 @@ fn run() -> Result<KakMessage, KakMessage> {
write!(f, "reg '\"'")?; write!(f, "reg '\"'")?;
let iter: Box<dyn Iterator<Item = _>> = if options.reverse { let iter: Box<dyn Iterator<Item = _>> = if sort_options.reverse {
Box::new(zipped.iter().rev()) Box::new(zipped.iter().rev())
} else { } else {
Box::new(zipped.iter()) Box::new(zipped.iter())