From 8ec3ab33389ca1058cc90993e9d99c4591952b90 Mon Sep 17 00:00:00 2001 From: Austen Adler Date: Thu, 9 Feb 2023 23:27:26 -0500 Subject: [PATCH] Add join command --- kakplugin/src/lib.rs | 5 +---- kakplugin/src/types.rs | 40 ++++++++++++++++++++++++++++++++++++++++ src/join.rs | 14 ++++++++++++++ src/main.rs | 10 +++++++--- 4 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 src/join.rs diff --git a/kakplugin/src/lib.rs b/kakplugin/src/lib.rs index 20f0135..a8b6adb 100644 --- a/kakplugin/src/lib.rs +++ b/kakplugin/src/lib.rs @@ -57,10 +57,7 @@ where /// # Errors /// /// Will return `Err` if command fifo could not be opened, read from, or written to -pub fn get_selections_desc_unordered(keys: Option) -> Result, KakError> -where - S: AsRef, -{ +pub fn get_selections_desc_unordered(keys: Option<&str>) -> Result, KakError> { response("%val{selections_desc}", keys.as_ref())? .iter() .map(|sd| SelectionDesc::from_str(sd)) diff --git a/kakplugin/src/types.rs b/kakplugin/src/types.rs index 3458ee6..78124f6 100644 --- a/kakplugin/src/types.rs +++ b/kakplugin/src/types.rs @@ -86,6 +86,46 @@ impl SelectionDesc { s.right.row - s.left.row + 1 } + /// Gets the smallest selection that encompases both selections + /// + /// ```rust + /// let sel1 = SelectionDesc { + /// left: AnchorPosition { row: 10, col: 16 }, + /// right: AnchorPosition { row: 1, col: 14 }, + /// }; + /// let sel2 = SelectionDesc { + /// left: AnchorPosition { row: 64, col: 10 }, + /// right: AnchorPosition { row: 1, col: 100 }, + /// }; + /// let expected_bounding = SelectionDesc { + /// left: AnchorPosition { row: 1, col: 14 }, + /// right: AnchorPosition { row: 64, col: 27 }, + /// }; + /// assert_eq!(sel1.rev().bounding_selection(&sel1), sel1.sort()); + /// assert_eq!(sel2.bounding_selection(&sel1), expected_bounding.sort()); + /// assert_eq!(sel2.rev().bounding_selection(&sel1.rev()), expected_bounding.sort()); + /// assert_eq!(sel2.rev().bounding_selection(&sel1), expected_bounding.sort()); + /// ``` + pub fn bounding_selection(&self, other: SD) -> Self + where + SD: AsRef, + { + // So left is the minimum and right is the maximum + let (a, b) = (self.sort(), other.as_ref().sort()); + + Self { + left: min(a.left, b.left), + right: max(a.right, b.right), + } + } + + pub fn rev(&self) -> Self { + Self { + left: self.right, + right: self.left, + } + } + #[must_use] pub fn sort(&self) -> Self { if self.left < self.right { diff --git a/src/join.rs b/src/join.rs new file mode 100644 index 0000000..8a16408 --- /dev/null +++ b/src/join.rs @@ -0,0 +1,14 @@ +use kakplugin::{get_selections_desc_unordered, set_selections_desc, KakError}; + +#[derive(clap::StructOpt, Debug)] +pub struct Options; + +pub fn join(_options: &Options) -> Result { + set_selections_desc( + get_selections_desc_unordered(None)? + .into_iter() + .reduce(|acc, sd| acc.bounding_selection(sd)), + )?; + + Ok(format!("Joined all selections")) +} diff --git a/src/main.rs b/src/main.rs index 24e509b..6d4f153 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,12 +10,13 @@ #![feature(array_chunks)] mod box_; -mod rev; mod errors; mod incr; mod invert; +mod join; mod math_eval; mod pad; +mod rev; mod set; mod shuf; mod sort; @@ -70,8 +71,10 @@ enum Commands { Decr(incr::Options), #[clap(about = "Decrement selections")] Incr(incr::Options), - #[clap(about = "Reverse selectinos")] - Rev(rev::Options) + #[clap(about = "Reverse selections")] + Rev(rev::Options), + #[clap(about = "Join selections")] + Join(join::Options), } fn main() { @@ -123,5 +126,6 @@ fn run() -> Result { Commands::Incr(o) => incr::incr(o, true), Commands::Decr(o) => incr::incr(o, false), Commands::Rev(o) => rev::rev(o), + Commands::Join(o) => join::join(o), } }