diff --git a/src/keep_every.rs b/src/keep_every.rs new file mode 100644 index 0000000..3a36d06 --- /dev/null +++ b/src/keep_every.rs @@ -0,0 +1,65 @@ +use itertools::Itertools; +use kakplugin::{get_selections_desc_unordered, set_selections_desc, KakError, SelectionDesc}; + +#[derive(Debug, clap::Args)] +pub struct Options { + #[clap(index = 1, value_parser = clap::value_parser!(u16).range(2..))] + keep_every: u16, +} + +pub fn keep_every(options: &Options) -> Result { + let selections_desc = get_selections_desc_unordered(None)?; + let old_count = selections_desc.len(); + + let new_selections_desc = apply(options, &selections_desc); + + set_selections_desc(new_selections_desc.iter())?; + + let new_count = new_selections_desc.len(); + + Ok(format!("{} kept from {}", new_count, old_count)) +} + +fn apply(options: &Options, selections_desc: &[SelectionDesc]) -> Vec { + selections_desc + .iter() + .chunks(options.keep_every.into()) + .into_iter() + .flat_map(|mut it| it.next()) + .copied() + .collect::>() +} + +#[cfg(test)] +mod tests { + // Selection desc creator + macro_rules! sd { + ($a:expr) => {{ + sd!($a, $a) + }}; + ($b:expr, $d:expr) => {{ + sd!(1, $b, 1, $d) + }}; + ($a:expr, $b:expr,$c:expr,$d:expr) => {{ + SelectionDesc { + left: AnchorPosition { row: $a, col: $b }, + right: AnchorPosition { row: $c, col: $d }, + } + }}; + } + + use kakplugin::{AnchorPosition, SelectionDesc}; + + use super::*; + #[test] + fn test() { + assert_eq!(apply(&Options { keep_every: 2 }, &[sd!(1),]), &[sd!(1),]); + assert_eq!( + apply( + &Options { keep_every: 2 }, + &[sd!(1), sd!(2), sd!(3), sd!(4), sd!(5), sd!(6), sd!(7),] + ), + &[sd!(1), sd!(3), sd!(5), sd!(7),] + ); + } +} diff --git a/src/main.rs b/src/main.rs index 6d4f153..f6730d2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,7 @@ mod errors; mod incr; mod invert; mod join; +mod keep_every; mod math_eval; mod pad; mod rev; @@ -75,6 +76,8 @@ enum Commands { Rev(rev::Options), #[clap(about = "Join selections")] Join(join::Options), + #[clap(about = "Keep a subset of selections", visible_aliases = &["keep"])] + KeepEvery(keep_every::Options), } fn main() { @@ -127,5 +130,6 @@ fn run() -> Result { Commands::Decr(o) => incr::incr(o, false), Commands::Rev(o) => rev::rev(o), Commands::Join(o) => join::join(o), + Commands::KeepEvery(o) => keep_every::keep_every(o), } }