Improve main.rs fifos

This commit is contained in:
Austen Adler 2022-01-29 10:23:25 -05:00
parent c15b86654b
commit aa1b27280e
2 changed files with 71 additions and 41 deletions

View File

@ -47,7 +47,8 @@ define-command sort-selections -params 0.. %{
# TODO: Send additional parameters # TODO: Send additional parameters
rust-selection-sort -R "$regex" $args -- "$@" > "$kak_command_fifo" rust-selection-sort -R "$regex" -f "$kak_command_fifo" -- "$@"
} }
exec R exec R
} }

View File

@ -1,21 +1,29 @@
#![warn(clippy::all, clippy::pedantic, clippy::nursery, clippy::cargo)] #![warn(clippy::all, clippy::pedantic, clippy::nursery, clippy::cargo)]
mod errors;
use alphanumeric_sort::compare_str; use alphanumeric_sort::compare_str;
use clap::Parser; use clap::Parser;
use errors::KakMessage;
use regex::Regex; use regex::Regex;
use std::env;
use std::fs;
use std::fs::File;
use std::fs::OpenOptions;
use std::io::Write;
struct KakMessage(String, Option<String>); #[derive(Parser, Debug)]
#[derive(Parser)]
#[clap(about, version, author)] #[clap(about, version, author)]
struct Options { struct Options {
// 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,
#[clap(index = 1)]
regex: String,
#[clap(short = 'S', long)] #[clap(short = 'S', long)]
// TODO: Can we invert a boolean? This name is terrible // TODO: Can we invert a boolean? This name is terrible
no_skip_whitespace: bool, no_skip_whitespace: bool,
#[clap(short = 'R', long, required = true)]
regex: String,
#[clap(multiple_occurrences = true, required = true)]
selections: Vec<String>,
#[clap(short, long)] #[clap(short, long)]
lexicographic_sort: bool, lexicographic_sort: bool,
#[clap(short, long)] #[clap(short, long)]
@ -31,29 +39,36 @@ fn main() {
fn send_message(msg: &KakMessage) { fn send_message(msg: &KakMessage) {
// TODO: This isn't echoing anything // TODO: This isn't echoing anything
let msg_str = msg.0.replace('\'', "''"); eprintln!("{} (Debug info: {:?})", msg.0, msg.1);
print!("echo '{}';", msg_str);
if let Some(debug_info) = &msg.1 { let msg_str = msg.0.replace('\'', "''");
print!("echo -debug '{}';", msg_str); let mut f = open_command_fifo().unwrap();
print!("echo -debug '{}';", debug_info.replace('\'', "''"));
write!(f, "echo '{}';", msg_str).unwrap();
write!(f, "echo -debug '{}';", msg_str).unwrap();
if let Some(debug_msg_str) = &msg.1 {
write!(f, "echo -debug '{}';", debug_msg_str.replace('\'', "''")).unwrap();
} }
} }
fn run() -> Result<(), KakMessage> { fn run() -> Result<(), KakMessage> {
let options = Options::try_parse()?; let options = Options::try_parse().map_err(|e| {
KakMessage(
"Error parsing arguments".to_string(),
Some(format!("Could not parse: {:?}", e)),
)
})?;
let replacement_re = options.regex; let re = Regex::new(&options.regex)
.map_err(|_| format!("Invalid regular expression: {}", options.regex))?;
let re = Regex::new(&replacement_re) let selections = read_selections()?;
.map_err(|_| format!("Invalid regular expression: {}", replacement_re))?;
let mut zipped = options let mut zipped = selections
.selections
.iter() .iter()
.zip( .zip(
options selections
.selections
.iter() .iter()
.map(|a| { .map(|a| {
if options.no_skip_whitespace { if options.no_skip_whitespace {
@ -83,7 +98,9 @@ fn run() -> Result<(), KakMessage> {
} }
}); });
print!("reg '\"'"); let mut f = open_command_fifo()?;
write!(f, "reg '\"'")?;
let iter: Box<dyn Iterator<Item = _>> = if options.reverse { let iter: Box<dyn Iterator<Item = _>> = if options.reverse {
Box::new(zipped.iter().rev()) Box::new(zipped.iter().rev())
@ -93,32 +110,44 @@ fn run() -> Result<(), KakMessage> {
for i in iter { for i in iter {
let new_selection = i.0.replace('\'', "''"); let new_selection = i.0.replace('\'', "''");
print!(" '{}'", new_selection); write!(f, " '{}'", new_selection)?;
} }
print!(" ;"); write!(f, " ;")?;
Ok(()) Ok(())
} }
impl From<std::io::Error> for KakMessage { fn read_selections() -> Result<Vec<String>, KakMessage> {
fn from(err: std::io::Error) -> Self { {
Self( let mut f = open_command_fifo()?;
"Error writing to fifo".to_string(),
Some(format!("{:?}", err)), write!(
) f,
"echo -quoting shell -to-file {} -- %val{{selections}}",
get_var("kak_response_fifo")?
)?;
} }
let selections = shellwords::split(&fs::read_to_string(&get_var("kak_response_fifo")?)?)?;
Ok(selections)
} }
impl From<clap::Error> for KakMessage { fn open_command_fifo() -> Result<File, KakMessage> {
fn from(err: clap::Error) -> Self { OpenOptions::new()
Self( .write(true)
"Error parsing arguments".to_string(), .append(true)
Some(format!("{:?}", err)), // Some(err.message.pieces.map(|p| p.0).join()), .open(&get_var("kak_command_fifo")?)
) .map_err(|e| e.into())
}
} }
impl From<String> for KakMessage { fn get_var(var_name: &str) -> Result<String, KakMessage> {
fn from(err: String) -> Self { env::var(var_name).map_err(|e| match e {
Self(err, None) env::VarError::NotPresent => {
} KakMessage(format!("Env var {} is not defined", var_name), None)
}
env::VarError::NotUnicode(_) => {
KakMessage(format!("Env var {} is not unicode", var_name), None)
}
})
} }