mirror of
https://github.com/FliegendeWurst/tmux-thumbs.git
synced 2024-11-22 21:05:00 +00:00
Add multi selection
This commit is contained in:
parent
8ae9fa9137
commit
741a5bd927
30
src/main.rs
30
src/main.rs
@ -64,6 +64,12 @@ fn app_args<'a>() -> clap::ArgMatches<'a> {
|
|||||||
.long("select-bg-color")
|
.long("select-bg-color")
|
||||||
.default_value("black"),
|
.default_value("black"),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("multi")
|
||||||
|
.help("Enable multi-selection")
|
||||||
|
.long("multi")
|
||||||
|
.short("m"),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("reverse")
|
Arg::with_name("reverse")
|
||||||
.help("Reverse the order for assigned hints")
|
.help("Reverse the order for assigned hints")
|
||||||
@ -105,6 +111,7 @@ fn main() {
|
|||||||
let format = args.value_of("format").unwrap();
|
let format = args.value_of("format").unwrap();
|
||||||
let alphabet = args.value_of("alphabet").unwrap();
|
let alphabet = args.value_of("alphabet").unwrap();
|
||||||
let position = args.value_of("position").unwrap();
|
let position = args.value_of("position").unwrap();
|
||||||
|
let multi = args.is_present("multi");
|
||||||
let reverse = args.is_present("reverse");
|
let reverse = args.is_present("reverse");
|
||||||
let unique = args.is_present("unique");
|
let unique = args.is_present("unique");
|
||||||
let contrast = args.is_present("contrast");
|
let contrast = args.is_present("contrast");
|
||||||
@ -136,6 +143,7 @@ fn main() {
|
|||||||
let selected = {
|
let selected = {
|
||||||
let mut viewbox = view::View::new(
|
let mut viewbox = view::View::new(
|
||||||
&mut state,
|
&mut state,
|
||||||
|
multi,
|
||||||
reverse,
|
reverse,
|
||||||
unique,
|
unique,
|
||||||
contrast,
|
contrast,
|
||||||
@ -151,19 +159,21 @@ fn main() {
|
|||||||
viewbox.present()
|
viewbox.present()
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some((text, upcase)) = selected {
|
if !selected.is_empty() {
|
||||||
let mut output = format.to_string();
|
for (text, upcase) in selected.iter() {
|
||||||
|
let mut output = format.to_string();
|
||||||
|
|
||||||
let upcase_value = if upcase {
|
let upcase_value = if *upcase { "true" } else { "false" };
|
||||||
"true"
|
|
||||||
} else {
|
|
||||||
"false"
|
|
||||||
};
|
|
||||||
|
|
||||||
output = str::replace(&output, "%U", upcase_value);
|
output = str::replace(&output, "%U", upcase_value);
|
||||||
output = str::replace(&output, "%H", text.as_str());
|
output = str::replace(&output, "%H", text.as_str());
|
||||||
|
|
||||||
print!("{}", output);
|
if multi {
|
||||||
|
println!("{}", output);
|
||||||
|
} else {
|
||||||
|
print!("{}", output);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
::std::process::exit(1);
|
::std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
39
src/view.rs
39
src/view.rs
@ -7,6 +7,7 @@ use std::default::Default;
|
|||||||
pub struct View<'a> {
|
pub struct View<'a> {
|
||||||
state: &'a mut state::State<'a>,
|
state: &'a mut state::State<'a>,
|
||||||
skip: usize,
|
skip: usize,
|
||||||
|
multi: bool,
|
||||||
reverse: bool,
|
reverse: bool,
|
||||||
unique: bool,
|
unique: bool,
|
||||||
contrast: bool,
|
contrast: bool,
|
||||||
@ -22,6 +23,7 @@ pub struct View<'a> {
|
|||||||
impl<'a> View<'a> {
|
impl<'a> View<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
state: &'a mut state::State<'a>,
|
state: &'a mut state::State<'a>,
|
||||||
|
multi: bool,
|
||||||
reverse: bool,
|
reverse: bool,
|
||||||
unique: bool,
|
unique: bool,
|
||||||
contrast: bool,
|
contrast: bool,
|
||||||
@ -36,6 +38,7 @@ impl<'a> View<'a> {
|
|||||||
View {
|
View {
|
||||||
state: state,
|
state: state,
|
||||||
skip: 0,
|
skip: 0,
|
||||||
|
multi: multi,
|
||||||
reverse: reverse,
|
reverse: reverse,
|
||||||
unique: unique,
|
unique: unique,
|
||||||
contrast: contrast,
|
contrast: contrast,
|
||||||
@ -71,7 +74,7 @@ impl<'a> View<'a> {
|
|||||||
text
|
text
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn present(&mut self) -> Option<(String, bool)> {
|
pub fn present(&mut self) -> Vec<(String, bool)> {
|
||||||
let mut rustbox = match RustBox::init(Default::default()) {
|
let mut rustbox = match RustBox::init(Default::default()) {
|
||||||
Result::Ok(v) => v,
|
Result::Ok(v) => v,
|
||||||
Result::Err(e) => panic!("{}", e),
|
Result::Err(e) => panic!("{}", e),
|
||||||
@ -88,6 +91,7 @@ impl<'a> View<'a> {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.clone();
|
.clone();
|
||||||
let mut selected;
|
let mut selected;
|
||||||
|
let mut chosen = vec![];
|
||||||
|
|
||||||
self.skip = if self.reverse { matches.len() - 1 } else { 0 };
|
self.skip = if self.reverse { matches.len() - 1 } else { 0 };
|
||||||
|
|
||||||
@ -167,10 +171,20 @@ impl<'a> View<'a> {
|
|||||||
match rustbox.poll_event(false) {
|
match rustbox.poll_event(false) {
|
||||||
Ok(rustbox::Event::KeyEvent(key)) => match key {
|
Ok(rustbox::Event::KeyEvent(key)) => match key {
|
||||||
Key::Esc => {
|
Key::Esc => {
|
||||||
break;
|
if self.multi && !typed_hint.is_empty() {
|
||||||
|
typed_hint.clear();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Key::Enter => match matches.iter().enumerate().find(|&h| h.0 == self.skip) {
|
Key::Enter => match matches.iter().enumerate().find(|&h| h.0 == self.skip) {
|
||||||
Some(hm) => return Some((hm.1.text.to_string(), false)),
|
Some(hm) => {
|
||||||
|
chosen.push((hm.1.text.to_string(), false));
|
||||||
|
|
||||||
|
if !self.multi {
|
||||||
|
return chosen;
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => panic!("Match not found?"),
|
_ => panic!("Match not found?"),
|
||||||
},
|
},
|
||||||
Key::Up => {
|
Key::Up => {
|
||||||
@ -186,6 +200,10 @@ impl<'a> View<'a> {
|
|||||||
self.next(matches.len() - 1);
|
self.next(matches.len() - 1);
|
||||||
}
|
}
|
||||||
Key::Char(ch) => {
|
Key::Char(ch) => {
|
||||||
|
if ch == ' ' && self.multi {
|
||||||
|
return chosen;
|
||||||
|
}
|
||||||
|
|
||||||
let key = ch.to_string();
|
let key = ch.to_string();
|
||||||
let lower_key = key.to_lowercase();
|
let lower_key = key.to_lowercase();
|
||||||
|
|
||||||
@ -195,9 +213,17 @@ impl<'a> View<'a> {
|
|||||||
.iter()
|
.iter()
|
||||||
.find(|mat| mat.hint == Some(typed_hint.clone()))
|
.find(|mat| mat.hint == Some(typed_hint.clone()))
|
||||||
{
|
{
|
||||||
Some(mat) => return Some((mat.text.to_string(), key != lower_key)),
|
Some(mat) => {
|
||||||
|
chosen.push((mat.text.to_string(), key != lower_key));
|
||||||
|
|
||||||
|
if self.multi {
|
||||||
|
typed_hint.clear();
|
||||||
|
} else {
|
||||||
|
return chosen;
|
||||||
|
}
|
||||||
|
}
|
||||||
None => {
|
None => {
|
||||||
if typed_hint.len() >= longest_hint.len() {
|
if !self.multi && typed_hint.len() >= longest_hint.len() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,7 +236,7 @@ impl<'a> View<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
chosen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,6 +256,7 @@ mod tests {
|
|||||||
let mut view = View {
|
let mut view = View {
|
||||||
state: &mut state,
|
state: &mut state,
|
||||||
skip: 0,
|
skip: 0,
|
||||||
|
multi: false,
|
||||||
reverse: false,
|
reverse: false,
|
||||||
unique: false,
|
unique: false,
|
||||||
contrast: false,
|
contrast: false,
|
||||||
|
Loading…
Reference in New Issue
Block a user