diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/README.md b/README.md index c04c83a..f3b1548 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,13 @@ # Select Option -Creates a tui selector based off of input args. -`select_option a b c` will create a selector for a, b, c. +Creates a tui selector based off of `stdin`. +`printf '1\n2\n3' | select_option` will create a selector for a, b, c. Navigate with F-keys, j/k, or arrow keys, then press enter on your selection. This will print out the selected option to stdout. +## Usecases + +Selecting a drive from the system +```bash +lsblk -lno type,name | grep part | awk '{ print "/dev/" $2 }' | select_option +``` diff --git a/src/main.rs b/src/main.rs index d4aef89..21c2d48 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,16 @@ -use std::{env::args, io}; +use std::{env::args, io::{self, BufRead, Read, stdin}}; use ratatui::{ DefaultTerminal, Frame, crossterm::event::{self, Event}, layout::{self, Constraint, Layout}, style::{Style, palette::material::{BLACK, WHITE}}, widgets::{Block, BorderType, Paragraph} }; fn main() -> Result<(), std::io::Error> { - let mut opts = Vec::new(); - args().skip(1).for_each(|a| opts.push(a)); + // let mut buffer = Vec::new(); + let mut buffer = String::new(); + let stdin = io::stdin(); + let mut handle = stdin.lock(); + handle.read_to_string(&mut buffer)?; + let opts = buffer.lines().collect::>(); let mut app = App::new(opts); let term = ratatui::init(); @@ -20,13 +24,13 @@ fn main() -> Result<(), std::io::Error> { return res; } -struct App { +struct App<'a> { exit: bool, - options: Vec, + options: Vec<&'a str>, index: usize, } -impl App { - pub fn new(opts: Vec) -> Self { +impl<'a> App<'a> { + pub fn new(opts: Vec<&'a str>) -> Self { Self { exit: false, options: opts, @@ -69,6 +73,16 @@ impl App { } fn handle_events(&mut self) -> io::Result<()> { + fn dec(a: &mut App) { + a.index = a.index.saturating_sub(1); + } + + fn inc(a: &mut App) { + if a.index < a.options.len()-1 { + a.index += 1 + } + } + if let Ok(k) = event::read() { if let Event::Key(e) = k { match e.code { @@ -82,12 +96,12 @@ impl App { self.exit = true; } }, - event::KeyCode::Up => self.index = self.index.saturating_sub(1), - event::KeyCode::Down => self.index += 1, + event::KeyCode::Up => dec(self), + event::KeyCode::Down => inc(self), event::KeyCode::Char(c) => { match c { - 'k' => self.index = self.index.saturating_sub(1), - 'j' => self.index += 1, + 'k' => dec(self), + 'j' => inc(self), _ => {} } },