From 801c484d763e7c18711547e4520dc6b463854d0e Mon Sep 17 00:00:00 2001 From: Austen Adler Date: Sun, 2 Oct 2022 12:45:07 -0400 Subject: [PATCH] Update stdin --- kakplugin/src/errors.rs | 16 +++++++++++ kakplugin/src/lib.rs | 59 +++++++++++++++++++++++++++++++++-------- src/main.rs | 1 - src/set.rs | 6 ++--- src/stdin.rs | 23 +++++++++++----- 5 files changed, 83 insertions(+), 22 deletions(-) diff --git a/kakplugin/src/errors.rs b/kakplugin/src/errors.rs index cf69abc..3d31abc 100644 --- a/kakplugin/src/errors.rs +++ b/kakplugin/src/errors.rs @@ -8,6 +8,8 @@ pub enum KakError { EnvVarUnicode(String), /// There was an error parsing a response from kak Parse(String), + /// The string could not be converted into UTF8 + Utf8Error(std::string::FromUtf8Error), /// There was an error with a response kak gave KakResponse(String), /// IO Error @@ -30,6 +32,7 @@ impl KakError { Self::EnvVarNotSet(e) => e.clone(), Self::EnvVarUnicode(e) => e.clone(), Self::Parse(e) => e.clone(), + Self::Utf8Error(e) => e.to_string(), Self::KakResponse(e) => e.clone(), Self::Io(e) => format!("{e:?}"), Self::NotImplemented(e) => e.to_string(), @@ -49,6 +52,7 @@ impl Display for KakError { Self::EnvVarNotSet(_) => write!(f, "env var not set"), Self::EnvVarUnicode(_) => write!(f, "env var not unicode"), Self::Parse(_) => write!(f, "Could not parse"), + Self::Utf8Error(_) => write!(f, "The string is not valid UTF-8"), Self::KakResponse(_) => write!(f, "Invalid kak response"), Self::Io(_) => write!(f, "IO error"), Self::NotImplemented(_) => write!(f, "Not Implemented"), @@ -62,6 +66,12 @@ impl Display for KakError { } } +impl From for KakError { + fn from(_e: std::convert::Infallible) -> Self { + Self::NotImplemented("Infallible error encountered") + } +} + impl From for KakError { fn from(e: std::io::Error) -> Self { Self::Io(e) @@ -79,3 +89,9 @@ impl From for KakError { Self::Parse(format!("Could not parse as integer: {e:?}")) } } + +impl From for KakError { + fn from(e: std::string::FromUtf8Error) -> Self { + Self::Utf8Error(e) + } +} diff --git a/kakplugin/src/lib.rs b/kakplugin/src/lib.rs index 189eda6..dfa9cb8 100644 --- a/kakplugin/src/lib.rs +++ b/kakplugin/src/lib.rs @@ -56,9 +56,9 @@ where // register: &str, // ) -> Result, KakError> { // // TODO: Escape register -// let subselections = get_selections_with_desc()?; +// let subselections = get_selections_with_desc_unordered()?; // exec(format!("\"{}z", register.replace('\'', "''")))?; -// let selections = get_selections_with_desc()?; +// let selections = get_selections_with_desc_unordered()?; // for sel in selections { // for i in subselections {} @@ -73,7 +73,9 @@ where /// /// Will return `Err` if command fifo could not be opened, read from, or written to, /// or if `selections.len() != selections_desc.len` -pub fn get_selections_with_desc(keys: Option<&'_ str>) -> Result, KakError> { +pub fn get_selections_with_desc_unordered( + keys: Option<&'_ str>, +) -> Result, KakError> { let mut selections = get_selections(keys)?; let selections_desc = get_selections_desc_unordered(keys)?; @@ -118,10 +120,8 @@ pub fn get_selections_with_desc(keys: Option<&'_ str>) -> Result, -) -> Result, KakError> { - let mut ret = get_selections_with_desc(keys)?; +pub fn get_selections_with_desc(keys: Option<&'_ str>) -> Result, KakError> { + let mut ret = get_selections_with_desc_unordered(keys)?; ret.sort_by_key(|s| s.desc.sort()); Ok(ret) } @@ -129,10 +129,11 @@ pub fn get_selections_with_desc_ordered( /// # Errors /// /// Will return `Err` if command fifo could not be opened, read from, or written to -pub fn set_selections<'a, I, S: 'a>(selections: I) -> Result<(), KakError> +pub fn set_selections_failable<'a, I, S: 'a, E>(selections: I) -> Result where - I: IntoIterator, + I: IntoIterator>, S: AsRef + Clone + Display, + E: Into, { let mut selections_iter = selections.into_iter().peekable(); if selections_iter.peek().is_none() { @@ -140,13 +141,49 @@ where } let mut f = open_command_fifo()?; + let mut num_written: usize = 0; + write!(f, "set-register '\"'")?; for i in selections_iter { - write!(f, " '{}'", escape(i.as_ref()))?; + num_written = num_written.saturating_add(1); + // eprintln!( + // "Got response: {:?}", + // i.map_err(Into::into)?.clone().as_ref() + // ); + write!(f, " '{}'", escape(i.map_err(Into::into)?.as_ref()))?; } + write!(f, "; execute-keys R;")?; f.flush()?; - Ok(()) + Ok(num_written) +} + +/// # Errors +/// +/// Will return `Err` if command fifo could not be opened, read from, or written to +pub fn set_selections<'a, I, S: 'a>(selections: I) -> Result +where + I: IntoIterator, + S: AsRef + Clone + Display, +{ + set_selections_failable( + selections + .into_iter() + .map(|s| -> Result<_, std::convert::Infallible> { Ok(s) }), + ) + // let mut selections_iter = selections.into_iter().peekable(); + // if selections_iter.peek().is_none() { + // return Err(KakError::SetEmptySelections); + // } + + // let mut f = open_command_fifo()?; + // write!(f, "set-register '\"'")?; + // for i in selections_iter { + // write!(f, " '{}'", escape(i.as_ref()))?; + // } + // write!(f, "; execute-keys R;")?; + // f.flush()?; + // Ok(()) } /// # Errors diff --git a/src/main.rs b/src/main.rs index 2228d0a..411b0f5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -79,7 +79,6 @@ enum Commands { 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::>(); - eprintln!("Len: {}, args: {:?}", args.len(), args); if args.len() >= 2 && args[1] == "shell-script-candidates" { if let Err(e) = kakplugin::generate_shell_script_candidates(Commands::VARIANTS) { eprintln!("{e:?}"); diff --git a/src/set.rs b/src/set.rs index 0817af9..2d7dc1a 100644 --- a/src/set.rs +++ b/src/set.rs @@ -1,8 +1,8 @@ // use crate::utils; use clap::ArgEnum; use kakplugin::{ - get_selections, get_selections_with_desc_ordered, set_selections, set_selections_desc, - types::Register, KakError, Selection, SelectionWithDesc, + get_selections, get_selections_with_desc, set_selections, set_selections_desc, types::Register, + KakError, Selection, SelectionWithDesc, }; use linked_hash_map::LinkedHashMap; use linked_hash_set::LinkedHashSet; @@ -156,7 +156,7 @@ fn reduce_selections( ) -> Result<(), KakError> { // The registers should have been read in a draft context // So the current selection will be unmodified - let selections_with_desc = get_selections_with_desc_ordered(None)?; + let selections_with_desc = get_selections_with_desc(None)?; set_selections_desc(selections_with_desc.into_iter().filter_map(|swd| { // Does not matter if the operation was - or & diff --git a/src/stdin.rs b/src/stdin.rs index 4ccefb6..0248a6e 100644 --- a/src/stdin.rs +++ b/src/stdin.rs @@ -1,11 +1,14 @@ -use kakplugin::{get_selections_with_desc, set_selections, KakError}; +use kakplugin::{get_selections_with_desc, set_selections_failable, KakError}; use std::{ + borrow::Cow, io::{BufRead, BufReader, Write}, process::{Command, Stdio}, }; #[derive(clap::StructOpt, Debug)] pub struct Options { + #[clap()] command: String, + #[clap(allow_hyphen_values = true)] args: Vec, } pub fn stdin(options: &Options) -> Result { @@ -24,18 +27,24 @@ pub fn stdin(options: &Options) -> Result { Ok(()) }); - set_selections( + let set_selections_result = set_selections_failable( BufReader::new(child.stdout.take().expect("Failed to get stdout")) .split(b'\0') - .map(|s| Ok(String::from_utf8_lossy(&s?).into_owned())) - .collect::, KakError>>()? - .iter(), - )?; + // TODO: Support non-utf8? + .map(|s| -> Result<_, KakError> { Ok(String::from_utf8(s?)?) }), + ); // Wait for the background process to exit + // Return its error (if there is one) first handle .join() .map_err(|_e| KakError::Custom("Could not join background process".to_string()))??; - Ok("stdin selections".into()) + // Now print any errors + let num_set = set_selections_result?; + + Ok(format!( + "Set {} selections from {}", + num_set, options.command + )) }