diff options
author | James Campos <james.r.campos@gmail.com> | 2020-04-28 17:15:38 -0700 |
---|---|---|
committer | James Campos <james.r.campos@gmail.com> | 2020-04-28 17:15:38 -0700 |
commit | a0ad98640ce8a4fb689dc41ab703a58202cd3ea7 (patch) | |
tree | 2bfbdb453f4287d4fac92d576f21d2fa32aaa619 /src | |
parent | 5c6dd582c3f527005680b48c4a7b336e2fd362ba (diff) | |
download | bk-a0ad98640ce8a4fb689dc41ab703a58202cd3ea7.tar.gz |
refactor
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 310 |
1 files changed, 144 insertions, 166 deletions
diff --git a/src/main.rs b/src/main.rs index d4c9642..4c11785 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ use std::io::{stdout, Error, Read, Write}; use crossterm::{ cursor, - event::{self, Event, KeyCode, MouseEvent}, + event::{self, Event, KeyCode}, queue, style::{Attribute, Print}, terminal::{self, ClearType}, @@ -199,32 +199,72 @@ struct Bk { search: String, } +struct Position(String, usize, usize); + impl Bk { - fn new( - path: &str, - chapter_idx: usize, - pos: usize, - pad: u16, - ) -> Result<Self, Error> { + fn new(pos: &Position, pad: u16) -> Result<Self, Error> { let (cols, rows) = terminal::size().unwrap(); - let mut epub = Epub::new(path)?; + let mut epub = Epub::new(&pos.0)?; let mut bk = Bk { mode: Mode::Read, chapter: Vec::new(), - chapter_idx, + chapter_idx: 0, nav_idx: 0, toc: epub.get_toc(), epub, - pos, + pos: 0, pad, cols, rows: rows as usize, search: String::new(), }; - bk.get_chapter(chapter_idx); - bk.pos = pos; + bk.get_chapter(pos.1); + bk.pos = pos.2; Ok(bk) } + fn run(&mut self) -> crossterm::Result<()> { + let mut stdout = stdout(); + queue!( + stdout, + terminal::EnterAlternateScreen, + cursor::Hide, + //event::EnableMouseCapture + )?; + terminal::enable_raw_mode()?; + + self.render(); + loop { + match event::read()? { + Event::Key(e) => match self.mode { + Mode::Read => { + if self.match_read(e.code) { + break; + } + } + Mode::Help => self.mode = Mode::Read, + Mode::Nav => self.match_nav(e.code), + Mode::Search => self.match_search(e.code), + }, + Event::Resize(cols, rows) => { + self.cols = cols; + self.rows = rows as usize; + self.get_chapter(self.chapter_idx); + } + // mouse isn't captured + Event::Mouse(_) => (), + } + self.render(); + } + + queue!( + stdout, + terminal::LeaveAlternateScreen, + cursor::Show, + //event::DisableMouseCapture + )?; + stdout.flush()?; + terminal::disable_raw_mode() + } fn get_chapter(&mut self, idx: usize) { let mut chapter = Vec::new(); let xml = self.epub.get_text(&self.toc[idx].1); @@ -287,15 +327,6 @@ impl Bk { self.pos = (self.chapter.len() / self.rows) * self.rows; } } - fn run(&mut self, e: Event) -> bool { - match self.mode { - Mode::Read => return self.run_read(e), - Mode::Nav => self.run_nav(e), - Mode::Help => self.mode = Mode::Read, - Mode::Search => self.run_search(e), - } - true - } fn really_search(&mut self, forwards: bool) { if forwards { if let Some(pos) = self.chapter[self.pos + 1..] @@ -311,130 +342,95 @@ impl Bk { self.pos = pos; } } - fn run_search(&mut self, e: Event) { - match e { - Event::Key(e) => match e.code { - KeyCode::Esc => { - self.search = String::new(); - self.mode = Mode::Read; - } - KeyCode::Enter => { - self.mode = Mode::Read; - self.really_search(true); - } - KeyCode::Char(c) => { - self.search.push(c); - } - _ => (), - }, + fn match_search(&mut self, kc: KeyCode) { + match kc { + KeyCode::Esc => { + self.search = String::new(); + self.mode = Mode::Read; + } + KeyCode::Enter => { + self.mode = Mode::Read; + self.really_search(true); + } + KeyCode::Char(c) => { + self.search.push(c); + } _ => (), } } - fn run_nav(&mut self, e: Event) { - match e { - Event::Key(e) => match e.code { - KeyCode::Esc | KeyCode::Tab | KeyCode::Char('q') => { - self.mode = Mode::Read - } - KeyCode::Down | KeyCode::Char('j') => { - if self.nav_idx < self.toc.len() - 1 { - self.nav_idx += 1; - } - } - KeyCode::Up | KeyCode::Char('k') => { - if self.nav_idx > 0 { - self.nav_idx -= 1; - } - } - KeyCode::Enter => { - self.get_chapter(self.nav_idx); - self.mode = Mode::Read; - } - KeyCode::Home | KeyCode::Char('g') => self.nav_idx = 0, - KeyCode::End | KeyCode::Char('G') => { - self.nav_idx = self.toc.len() - 1 - } - _ => (), - }, - Event::Mouse(e) => match e { - MouseEvent::ScrollDown(_, _, _) => { - if self.nav_idx < self.toc.len() - 1 { - self.nav_idx += 1; - } - } - MouseEvent::ScrollUp(_, _, _) => { - if self.nav_idx > 0 { - self.nav_idx -= 1; - } + fn match_nav(&mut self, kc: KeyCode) { + match kc { + KeyCode::Esc | KeyCode::Tab | KeyCode::Char('q') => { + self.mode = Mode::Read + } + KeyCode::Down | KeyCode::Char('j') => { + if self.nav_idx < self.toc.len() - 1 { + self.nav_idx += 1; } - MouseEvent::Down(event::MouseButton::Left, _, row, _) => { - self.get_chapter(row as usize); - self.mode = Mode::Read; + } + KeyCode::Up | KeyCode::Char('k') => { + if self.nav_idx > 0 { + self.nav_idx -= 1; } - _ => (), - }, + } + KeyCode::Enter => { + self.get_chapter(self.nav_idx); + self.mode = Mode::Read; + } + KeyCode::Home | KeyCode::Char('g') => self.nav_idx = 0, + KeyCode::End | KeyCode::Char('G') => { + self.nav_idx = self.toc.len() - 1 + } _ => (), } } - fn run_read(&mut self, e: Event) -> bool { - match e { - Event::Key(e) => match e.code { - KeyCode::Esc | KeyCode::Char('q') => return false, - KeyCode::Tab => self.start_nav(), - KeyCode::F(1) | KeyCode::Char('?') => self.mode = Mode::Help, - KeyCode::Char('/') => { - self.search = String::new(); - self.mode = Mode::Search; - } - KeyCode::Char('N') => { - self.really_search(false); - } - KeyCode::Char('n') => { - self.really_search(true); - } - KeyCode::End | KeyCode::Char('G') => { - self.pos = (self.chapter.len() / self.rows) * self.rows; - } - KeyCode::Home | KeyCode::Char('g') => self.pos = 0, - KeyCode::Char('d') => { - self.scroll_down(self.rows / 2); - } - KeyCode::Char('u') => { - self.scroll_up(self.rows / 2); - } - KeyCode::Up | KeyCode::Char('k') => { - self.scroll_up(1); - } - KeyCode::Left - | KeyCode::PageUp - | KeyCode::Char('b') - | KeyCode::Char('h') => { - self.scroll_up(self.rows); - } - KeyCode::Down | KeyCode::Char('j') => { - self.scroll_down(1); - } - KeyCode::Right - | KeyCode::PageDown - | KeyCode::Char('f') - | KeyCode::Char('l') - | KeyCode::Char(' ') => { - self.scroll_down(self.rows); - } - _ => (), - }, - Event::Mouse(e) => match e { - MouseEvent::ScrollDown(_, _, _) => self.scroll_down(3), - MouseEvent::ScrollUp(_, _, _) => self.scroll_up(3), - _ => (), - }, - Event::Resize(cols, rows) => { - self.cols = cols; - self.rows = rows as usize; - self.get_chapter(self.chapter_idx); + fn match_read(&mut self, kc: KeyCode) -> bool { + match kc { + KeyCode::Esc | KeyCode::Char('q') => return true, + KeyCode::Tab => self.start_nav(), + KeyCode::F(1) | KeyCode::Char('?') => self.mode = Mode::Help, + KeyCode::Char('/') => { + self.search = String::new(); + self.mode = Mode::Search; + } + KeyCode::Char('N') => { + self.really_search(false); + } + KeyCode::Char('n') => { + self.really_search(true); + } + KeyCode::End | KeyCode::Char('G') => { + self.pos = (self.chapter.len() / self.rows) * self.rows; + } + KeyCode::Home | KeyCode::Char('g') => self.pos = 0, + KeyCode::Char('d') => { + self.scroll_down(self.rows / 2); + } + KeyCode::Char('u') => { + self.scroll_up(self.rows / 2); + } + KeyCode::Up | KeyCode::Char('k') => { + self.scroll_up(1); + } + KeyCode::Left + | KeyCode::PageUp + | KeyCode::Char('b') + | KeyCode::Char('h') => { + self.scroll_up(self.rows); } + KeyCode::Down | KeyCode::Char('j') => { + self.scroll_down(1); + } + KeyCode::Right + | KeyCode::PageDown + | KeyCode::Char('f') + | KeyCode::Char('l') + | KeyCode::Char(' ') => { + self.scroll_down(self.rows); + } + _ => (), } - true + false } fn render(&self) { match self.mode { @@ -537,7 +533,7 @@ PageDown Right Space f l Page Down } } -fn restore() -> Option<(String, usize, usize)> { +fn restore() -> Option<Position> { let path = std::env::args().nth(1); let save_path = format!("{}/.local/share/bk", std::env::var("HOME").unwrap()); @@ -545,7 +541,7 @@ fn restore() -> Option<(String, usize, usize)> { let get_save = |s: String| { let mut lines = s.lines(); - ( + Position( lines.next().unwrap().to_string(), lines.next().unwrap().parse::<usize>().unwrap(), lines.next().unwrap().parse::<usize>().unwrap(), @@ -554,56 +550,38 @@ fn restore() -> Option<(String, usize, usize)> { match (save, path) { (Err(_), None) => None, - (Err(_), Some(path)) => Some((path, 0, 0)), + (Err(_), Some(path)) => Some(Position(path, 0, 0)), (Ok(save), None) => Some(get_save(save)), (Ok(save), Some(path)) => { let save = get_save(save); if save.0 == path { Some(save) } else { - Some((path, 0, 0)) + Some(Position(path, 0, 0)) } } } } -fn main() -> crossterm::Result<()> { - let (path, chapter, pos) = restore().unwrap_or_else(|| { +fn main() { + let pos = restore().unwrap_or_else(|| { println!("usage: bk path"); std::process::exit(1); }); - let mut bk = Bk::new(&path, chapter, pos, 3).unwrap_or_else(|e| { + let mut bk = Bk::new(&pos, 3).unwrap_or_else(|e| { println!("error reading epub: {}", e); std::process::exit(1); }); - let mut stdout = stdout(); - queue!( - stdout, - terminal::EnterAlternateScreen, - cursor::Hide, - event::EnableMouseCapture - )?; - terminal::enable_raw_mode()?; - - bk.render(); - while bk.run(event::read()?) { - bk.render(); - } + bk.run().unwrap(); std::fs::write( format!("{}/.local/share/bk", std::env::var("HOME").unwrap()), - format!("{}\n{}\n{}", path, bk.chapter_idx, bk.pos), + format!("{}\n{}\n{}", pos.0, bk.chapter_idx, bk.pos), ) - .unwrap(); - - queue!( - stdout, - terminal::LeaveAlternateScreen, - cursor::Show, - event::DisableMouseCapture - )?; - stdout.flush()?; - terminal::disable_raw_mode() + .unwrap_or_else(|e| { + println!("error saving position: {}", e); + std::process::exit(1); + }); } |