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),
/// 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<std::convert::Infallible> for KakError {
fn from(_e: std::convert::Infallible) -> Self {
Self::NotImplemented("Infallible error encountered")
}
}
impl From<std::io::Error> for KakError {
fn from(e: std::io::Error) -> Self {
Self::Io(e)
@ -79,3 +89,9 @@ impl From<ParseIntError> for KakError {
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,
// ) -> Result<Vec<SelectionWithSubselections>, 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<Vec<SelectionWithDesc>, KakError> {
pub fn get_selections_with_desc_unordered(
keys: Option<&'_ str>,
) -> Result<Vec<SelectionWithDesc>, 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<Vec<SelectionWi
/// 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
pub fn get_selections_with_desc_ordered(
keys: Option<&'_ str>,
) -> Result<Vec<SelectionWithDesc>, KakError> {
let mut ret = get_selections_with_desc(keys)?;
pub fn get_selections_with_desc(keys: Option<&'_ str>) -> Result<Vec<SelectionWithDesc>, 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<usize, KakError>
where
I: IntoIterator<Item = S>,
I: IntoIterator<Item = Result<S, E>>,
S: AsRef<str> + Clone + Display,
E: Into<KakError>,
{
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<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

View File

@ -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::<Vec<_>>();
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:?}");

View File

@ -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 &

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::{
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<String>,
}
pub fn stdin(options: &Options) -> Result<String, KakError> {
@ -24,18 +27,24 @@ pub fn stdin(options: &Options) -> Result<String, KakError> {
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::<Result<Vec<_>, 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
))
}