diff --git a/src/box_.rs b/src/box_.rs index 3923501..6ec2831 100644 --- a/src/box_.rs +++ b/src/box_.rs @@ -4,9 +4,12 @@ use kakplugin::{ use std::cmp::{max, min}; #[derive(clap::StructOpt, Debug)] pub struct Options { - // /// Bounding box mode, which selects the largest box to contain everything + /// Bounding box mode, which selects the largest box to contain everything #[clap(short, long, help = "Select the bonding box of all selections")] bounding_box: bool, + /// Excludes newlines from resulting selection + #[clap(short, long, help = "Do not include newlines")] + no_newline: bool, } pub fn box_(options: &Options) -> Result { @@ -61,12 +64,20 @@ where /// Implementation that converts each selection to a box with the top left corner at min(anchor.col, cursor.col) and bottom right at max(anchor.col, cursor.col) /// /// Do this by getting each selection, then getting each whole-row (col 0 to col max) and passing the range of whole-rows into helper `to_boxed_selections` -fn boxed_selections(_options: &Options) -> Result, KakError> { +fn boxed_selections(options: &Options) -> Result, KakError> { // The selections we want to box, one per box let selections_desc = get_selections_desc::<&str>(None)?; + let whole_line_selection_command = if options.no_newline { + // Select everything and only keep non-newlines + "s^[^\\n]+" + } else { + // Select everything and split + "" + }; + // Whole-row selections split on newline - let selections_desc_rows = get_selections_desc(Some(""))?; + let selections_desc_rows = get_selections_desc(Some(whole_line_selection_command))?; Ok(selections_desc .iter() diff --git a/src/invert.rs b/src/invert.rs index d275192..145e2f1 100644 --- a/src/invert.rs +++ b/src/invert.rs @@ -4,8 +4,12 @@ use kakplugin::{ }; use std::{fs, str::FromStr}; #[derive(clap::StructOpt, Debug)] -pub struct Options; -pub fn invert(_options: &Options) -> Result { +pub struct Options { + #[clap(short, long, help = "Do not include newlines")] + no_newline: bool, +} + +pub fn invert(options: &Options) -> Result { // The selections to invert let mut split_selections_desc: Vec<(usize, Vec)> = { // Split by multiline so subtraction is defined (see below) @@ -18,10 +22,18 @@ pub fn invert(_options: &Options) -> Result { let count_selections = split_selections_desc.len(); + let whole_document_selection_command = if options.no_newline { + // Select everything and only keep non-newlines + "%s^[^\\n]+" + } else { + // Select everything and split + "%" + }; + let document_descs: Vec = { // Every line in the document as a selectiondesc // Split by line because subtracting cross-multiline is not always defined for multiline selection descs (ex: 1.1,3.3 - 2.1,3.3 = 1.1,1.) - get_selections_desc(Some("%"))? + get_selections_desc(Some(whole_document_selection_command))? .into_iter() // dd - The full row selectiondesc, spanning from col 1 to the rightmost col, for every row in the file .map(|dd: SelectionDesc| { diff --git a/src/main.rs b/src/main.rs index 1d130ac..eeda230 100644 --- a/src/main.rs +++ b/src/main.rs @@ -48,7 +48,7 @@ enum Commands { Shuf(shuf::Options), #[clap(about = "Find unique selections based on optional regex match")] Uniq(uniq::Options), - #[clap(about = "Invert all selections", visible_aliases = &["inverse"])] + #[clap(about = "Invert all selections", visible_aliases = &["inv", "inverse"])] Invert(invert::Options), #[clap(about = "Evaluate selections as a math expression", visible_aliases = &["bc", "eval"])] MathEval(math_eval::Options),