Add box/square command
This commit is contained in:
parent
e7596f0276
commit
fac1ab37ea
93
src/box_.rs
Normal file
93
src/box_.rs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
use kakplugin::{
|
||||||
|
get_selections_desc, set_selections_desc, AnchorPosition, KakError, SelectionDesc,
|
||||||
|
};
|
||||||
|
use std::cmp::{max, min};
|
||||||
|
#[derive(clap::StructOpt, Debug)]
|
||||||
|
pub struct Options {
|
||||||
|
// /// 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,
|
||||||
|
// /// Allow selecting trailing newlines
|
||||||
|
// #[clap(short, long, help = "Allow selecting trailing newlines")]
|
||||||
|
// preserve_newlines: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn box_(options: &Options) -> Result<String, KakError> {
|
||||||
|
// TODO: Research if having multiple bounding boxes makes sense
|
||||||
|
// let ret_selection_descs = if options.bounding_box {
|
||||||
|
// // Get the bounding box and select it
|
||||||
|
// bounding_box(options)?
|
||||||
|
// } else {
|
||||||
|
// // Get a box per selection
|
||||||
|
// todo!("Implement per_selection(options: &Options);");
|
||||||
|
// };
|
||||||
|
|
||||||
|
let ret_selection_descs = bounding_box(options)?;
|
||||||
|
|
||||||
|
set_selections_desc(ret_selection_descs.iter())?;
|
||||||
|
|
||||||
|
Ok(format!("Box {} selections", ret_selection_descs.len()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bounding_box(_options: &Options) -> Result<Vec<SelectionDesc>, KakError> {
|
||||||
|
let selection_descs: Vec<SelectionDesc> = get_selections_desc()?
|
||||||
|
.iter()
|
||||||
|
// TODO: Do they need to be sorted?
|
||||||
|
.map(|sd| sd.sort())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let (leftmost_col, rightmost_col) = selection_descs
|
||||||
|
.iter()
|
||||||
|
// Extract the columns so they can be reduced
|
||||||
|
// Make the left one be the smaller one in case the first one is max or min (reduce function would not be called)
|
||||||
|
.map(|sd| {
|
||||||
|
(
|
||||||
|
min(sd.left.col, sd.right.col),
|
||||||
|
max(sd.left.col, sd.right.col),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
// Get the smallest column or row
|
||||||
|
.reduce(|(leftmost_col, rightmost_col), (left, right)| {
|
||||||
|
(
|
||||||
|
min(leftmost_col, min(left, right)),
|
||||||
|
max(rightmost_col, min(left, right)),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.ok_or_else(|| KakError::Custom(String::from("Selection is empty")))?;
|
||||||
|
|
||||||
|
// Now, split on newline
|
||||||
|
// TODO: Should I use <a-s>?
|
||||||
|
// kakplugin::cmd(&format!("exec 'S\\n<ret>'"))?;
|
||||||
|
kakplugin::cmd(&format!("exec '<a-s>'"))?;
|
||||||
|
// TODO: Here is where I might want selections to check if they end in newline
|
||||||
|
|
||||||
|
let mut ret_selection_descs: Vec<SelectionDesc> = vec![];
|
||||||
|
|
||||||
|
let split_selection_descs: Vec<SelectionDesc> =
|
||||||
|
get_selections_desc()?.iter().map(|sd| sd.sort()).collect();
|
||||||
|
|
||||||
|
for sd in &split_selection_descs {
|
||||||
|
if sd.left.col > rightmost_col || sd.right.col < leftmost_col {
|
||||||
|
// If this selection is out of bounds, exclude this line
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret_selection_descs.push(SelectionDesc {
|
||||||
|
left: AnchorPosition {
|
||||||
|
row: sd.left.row,
|
||||||
|
col: leftmost_col,
|
||||||
|
},
|
||||||
|
right: AnchorPosition {
|
||||||
|
row: sd.right.row,
|
||||||
|
col: rightmost_col,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// The left- and right-most col
|
||||||
|
|
||||||
|
// let subselection_descs
|
||||||
|
}
|
||||||
|
|
||||||
|
set_selections_desc(&ret_selection_descs[..])?;
|
||||||
|
|
||||||
|
Ok(ret_selection_descs)
|
||||||
|
}
|
@ -8,6 +8,7 @@
|
|||||||
// TODO: Remove
|
// TODO: Remove
|
||||||
#![allow(dead_code, unused_imports)]
|
#![allow(dead_code, unused_imports)]
|
||||||
|
|
||||||
|
mod box_;
|
||||||
mod errors;
|
mod errors;
|
||||||
mod math_eval;
|
mod math_eval;
|
||||||
mod set;
|
mod set;
|
||||||
@ -51,6 +52,8 @@ enum Commands {
|
|||||||
// Xargs(xargs::Options),
|
// Xargs(xargs::Options),
|
||||||
#[clap(about = "Pass each selection null terminated to a command")]
|
#[clap(about = "Pass each selection null terminated to a command")]
|
||||||
Stdin(stdin::Options),
|
Stdin(stdin::Options),
|
||||||
|
#[clap(about = "Make boxes out of selections", visible_aliases = &["square"])]
|
||||||
|
Box_(box_::Options),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -86,5 +89,6 @@ fn run() -> Result<String, KakError> {
|
|||||||
Commands::Set(o) => set::set(o),
|
Commands::Set(o) => set::set(o),
|
||||||
// Commands::Xargs(o) => xargs::xargs(o),
|
// Commands::Xargs(o) => xargs::xargs(o),
|
||||||
Commands::Stdin(o) => stdin::stdin(o),
|
Commands::Stdin(o) => stdin::stdin(o),
|
||||||
|
Commands::Box_(o) => box_::box_(o),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@ use evalexpr::{eval, Value};
|
|||||||
use kakplugin::{get_selections, open_command_fifo, KakError};
|
use kakplugin::{get_selections, open_command_fifo, KakError};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
|
// TODO: Context for log() and others
|
||||||
|
|
||||||
#[derive(clap::StructOpt, Debug)]
|
#[derive(clap::StructOpt, Debug)]
|
||||||
pub struct Options;
|
pub struct Options;
|
||||||
pub fn math_eval(_options: &Options) -> Result<String, KakError> {
|
pub fn math_eval(_options: &Options) -> Result<String, KakError> {
|
||||||
|
@ -19,7 +19,6 @@ pub fn stdin(options: &Options) -> Result<String, KakError> {
|
|||||||
let mut child_stdin = child.stdin.take().expect("Failed to open stdin");
|
let mut child_stdin = child.stdin.take().expect("Failed to open stdin");
|
||||||
let handle = std::thread::spawn(move || -> Result<(), KakError> {
|
let handle = std::thread::spawn(move || -> Result<(), KakError> {
|
||||||
for s in get_selections_with_desc()? {
|
for s in get_selections_with_desc()? {
|
||||||
eprintln!("Got selection {}", s.content);
|
|
||||||
write!(child_stdin, "{}\0", s.content)?;
|
write!(child_stdin, "{}\0", s.content)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -39,7 +39,6 @@ pub fn trim(options: &Options) -> Result<String, KakError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !options.no_preserve_newline && s.ends_with('\n') {
|
if !options.no_preserve_newline && s.ends_with('\n') {
|
||||||
eprintln!("Adding newline: {s:?}");
|
|
||||||
new_string.to_owned() + "\n"
|
new_string.to_owned() + "\n"
|
||||||
} else {
|
} else {
|
||||||
new_string.to_owned()
|
new_string.to_owned()
|
||||||
|
@ -20,14 +20,11 @@ pub fn xargs(options: &Options) -> Result<String, KakError> {
|
|||||||
let mut stdin = child.stdin.take().expect("Failed to open stdin");
|
let mut stdin = child.stdin.take().expect("Failed to open stdin");
|
||||||
let handle = std::thread::spawn(move || -> Result<(), KakError> {
|
let handle = std::thread::spawn(move || -> Result<(), KakError> {
|
||||||
for s in get_selections_with_desc()? {
|
for s in get_selections_with_desc()? {
|
||||||
eprintln!("Got selection {}", s.content);
|
|
||||||
write!(stdin, "{}\0", s.content)?;
|
write!(stdin, "{}\0", s.content)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
eprintln!("About t oreadvv");
|
|
||||||
|
|
||||||
set_selections(
|
set_selections(
|
||||||
BufReader::new(
|
BufReader::new(
|
||||||
child
|
child
|
||||||
|
Loading…
Reference in New Issue
Block a user