Update stdin

This commit is contained in:
Austen Adler 2022-10-02 12:45:07 -04:00
parent 093689c02b
commit 801c484d76
5 changed files with 83 additions and 22 deletions

View File

@ -8,6 +8,8 @@ pub enum KakError {
EnvVarUnicode(String), EnvVarUnicode(String),
/// There was an error parsing a response from kak /// There was an error parsing a response from kak
Parse(String), Parse(String),
/// The string could not be converted into UTF8
Utf8Error(std::string::FromUtf8Error),
/// There was an error with a response kak gave /// There was an error with a response kak gave
KakResponse(String), KakResponse(String),
/// IO Error /// IO Error
@ -30,6 +32,7 @@ impl KakError {
Self::EnvVarNotSet(e) => e.clone(), Self::EnvVarNotSet(e) => e.clone(),
Self::EnvVarUnicode(e) => e.clone(), Self::EnvVarUnicode(e) => e.clone(),
Self::Parse(e) => e.clone(), Self::Parse(e) => e.clone(),
Self::Utf8Error(e) => e.to_string(),
Self::KakResponse(e) => e.clone(), Self::KakResponse(e) => e.clone(),
Self::Io(e) => format!("{e:?}"), Self::Io(e) => format!("{e:?}"),
Self::NotImplemented(e) => e.to_string(), Self::NotImplemented(e) => e.to_string(),
@ -49,6 +52,7 @@ impl Display for KakError {
Self::EnvVarNotSet(_) => write!(f, "env var not set"), Self::EnvVarNotSet(_) => write!(f, "env var not set"),
Self::EnvVarUnicode(_) => write!(f, "env var not unicode"), Self::EnvVarUnicode(_) => write!(f, "env var not unicode"),
Self::Parse(_) => write!(f, "Could not parse"), 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::KakResponse(_) => write!(f, "Invalid kak response"),
Self::Io(_) => write!(f, "IO error"), Self::Io(_) => write!(f, "IO error"),
Self::NotImplemented(_) => write!(f, "Not Implemented"), Self::NotImplemented(_) => write!(f, "Not Implemented"),
@ -62,6 +66,12 @@ impl Display for KakError {
} }
} }
impl From<std::convert::Infallible> for KakError {
fn from(_e: std::convert::Infallible) -> Self {
Self::NotImplemented("Infallible error encountered")
}
}
impl From<std::io::Error> for KakError { impl From<std::io::Error> for KakError {
fn from(e: std::io::Error) -> Self { fn from(e: std::io::Error) -> Self {
Self::Io(e) Self::Io(e)
@ -79,3 +89,9 @@ impl From<ParseIntError> for KakError {
Self::Parse(format!("Could not parse as integer: {e:?}")) Self::Parse(format!("Could not parse as integer: {e:?}"))
} }
} }
impl From<std::string::FromUtf8Error> for KakError {
fn from(e: std::string::FromUtf8Error) -> Self {
Self::Utf8Error(e)
}
}

View File

@ -56,9 +56,9 @@ where
// register: &str, // register: &str,
// ) -> Result<Vec<SelectionWithSubselections>, KakError> { // ) -> Result<Vec<SelectionWithSubselections>, KakError> {
// // TODO: Escape register // // TODO: Escape register
// let subselections = get_selections_with_desc()?; // let subselections = get_selections_with_desc_unordered()?;
// exec(format!("\"{}z", register.replace('\'', "''")))?; // exec(format!("\"{}z", register.replace('\'', "''")))?;
// let selections = get_selections_with_desc()?; // let selections = get_selections_with_desc_unordered()?;
// for sel in selections { // for sel in selections {
// for i in subselections {} // for i in subselections {}
@ -73,7 +73,9 @@ where
/// ///
/// Will return `Err` if command fifo could not be opened, read from, or written to, /// Will return `Err` if command fifo could not be opened, read from, or written to,
/// or if `selections.len() != selections_desc.len` /// or if `selections.len() != selections_desc.len`
pub fn get_selections_with_desc(keys: Option<&'_ str>) -> Result<Vec<SelectionWithDesc>, KakError> { pub fn get_selections_with_desc_unordered(
keys: Option<&'_ str>,
) -> Result<Vec<SelectionWithDesc>, KakError> {
let mut selections = get_selections(keys)?; let mut selections = get_selections(keys)?;
let selections_desc = get_selections_desc_unordered(keys)?; let selections_desc = get_selections_desc_unordered(keys)?;
@ -118,10 +120,8 @@ pub fn get_selections_with_desc(keys: Option<&'_ str>) -> Result<Vec<SelectionWi
/// Return a vec of SelectionWithDesc, sorted in file (SelectionDesc) order /// Return a vec of SelectionWithDesc, sorted in file (SelectionDesc) order
/// ///
/// For example, the returned vec's order will be selection 1, 2, then 3 regardless of the primary selection /// For example, the returned vec's order will be selection 1, 2, then 3 regardless of the primary selection
pub fn get_selections_with_desc_ordered( pub fn get_selections_with_desc(keys: Option<&'_ str>) -> Result<Vec<SelectionWithDesc>, KakError> {
keys: Option<&'_ str>, let mut ret = get_selections_with_desc_unordered(keys)?;
) -> Result<Vec<SelectionWithDesc>, KakError> {
let mut ret = get_selections_with_desc(keys)?;
ret.sort_by_key(|s| s.desc.sort()); ret.sort_by_key(|s| s.desc.sort());
Ok(ret) Ok(ret)
} }
@ -129,10 +129,11 @@ pub fn get_selections_with_desc_ordered(
/// # Errors /// # Errors
/// ///
/// Will return `Err` if command fifo could not be opened, read from, or written to /// 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<usize, KakError>
where where
I: IntoIterator<Item = S>, I: IntoIterator<Item = Result<S, E>>,
S: AsRef<str> + Clone + Display, S: AsRef<str> + Clone + Display,
E: Into<KakError>,
{ {
let mut selections_iter = selections.into_iter().peekable(); let mut selections_iter = selections.into_iter().peekable();
if selections_iter.peek().is_none() { if selections_iter.peek().is_none() {
@ -140,13 +141,49 @@ where
} }
let mut f = open_command_fifo()?; let mut f = open_command_fifo()?;
let mut num_written: usize = 0;
write!(f, "set-register '\"'")?; write!(f, "set-register '\"'")?;
for i in selections_iter { 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;")?; write!(f, "; execute-keys R;")?;
f.flush()?; 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<usize, KakError>
where
I: IntoIterator<Item = S>,
S: AsRef<str> + 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 /// # Errors

View File

@ -79,7 +79,6 @@ enum Commands {
fn main() { fn main() {
// First, check if we are just getting candidates to run the program. kak_command_fifo is not needed for this // 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<_>>(); let args = env::args().collect::<Vec<_>>();
eprintln!("Len: {}, args: {:?}", args.len(), args);
if args.len() >= 2 && args[1] == "shell-script-candidates" { if args.len() >= 2 && args[1] == "shell-script-candidates" {
if let Err(e) = kakplugin::generate_shell_script_candidates(Commands::VARIANTS) { if let Err(e) = kakplugin::generate_shell_script_candidates(Commands::VARIANTS) {
eprintln!("{e:?}"); eprintln!("{e:?}");

View File

@ -1,8 +1,8 @@
// use crate::utils; // use crate::utils;
use clap::ArgEnum; use clap::ArgEnum;
use kakplugin::{ use kakplugin::{
get_selections, get_selections_with_desc_ordered, set_selections, set_selections_desc, get_selections, get_selections_with_desc, set_selections, set_selections_desc, types::Register,
types::Register, KakError, Selection, SelectionWithDesc, KakError, Selection, SelectionWithDesc,
}; };
use linked_hash_map::LinkedHashMap; use linked_hash_map::LinkedHashMap;
use linked_hash_set::LinkedHashSet; use linked_hash_set::LinkedHashSet;
@ -156,7 +156,7 @@ fn reduce_selections(
) -> Result<(), KakError> { ) -> Result<(), KakError> {
// The registers should have been read in a draft context // The registers should have been read in a draft context
// So the current selection will be unmodified // 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| { set_selections_desc(selections_with_desc.into_iter().filter_map(|swd| {
// Does not matter if the operation was - or & // Does not matter if the operation was - or &

View File

@ -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::{ use std::{
borrow::Cow,
io::{BufRead, BufReader, Write}, io::{BufRead, BufReader, Write},
process::{Command, Stdio}, process::{Command, Stdio},
}; };
#[derive(clap::StructOpt, Debug)] #[derive(clap::StructOpt, Debug)]
pub struct Options { pub struct Options {
#[clap()]
command: String, command: String,
#[clap(allow_hyphen_values = true)]
args: Vec<String>, args: Vec<String>,
} }
pub fn stdin(options: &Options) -> Result<String, KakError> { pub fn stdin(options: &Options) -> Result<String, KakError> {
@ -24,18 +27,24 @@ pub fn stdin(options: &Options) -> Result<String, KakError> {
Ok(()) Ok(())
}); });
set_selections( let set_selections_result = set_selections_failable(
BufReader::new(child.stdout.take().expect("Failed to get stdout")) BufReader::new(child.stdout.take().expect("Failed to get stdout"))
.split(b'\0') .split(b'\0')
.map(|s| Ok(String::from_utf8_lossy(&s?).into_owned())) // TODO: Support non-utf8?
.collect::<Result<Vec<_>, KakError>>()? .map(|s| -> Result<_, KakError> { Ok(String::from_utf8(s?)?) }),
.iter(), );
)?;
// Wait for the background process to exit // Wait for the background process to exit
// Return its error (if there is one) first
handle handle
.join() .join()
.map_err(|_e| KakError::Custom("Could not join background process".to_string()))??; .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
))
} }