diff options
| -rw-r--r-- | src/buffer/mod.rs | 18 | ||||
| -rw-r--r-- | src/buffer/threads.rs | 41 | ||||
| -rw-r--r-- | src/main.rs | 8 | ||||
| -rw-r--r-- | src/window.rs | 43 |
4 files changed, 79 insertions, 31 deletions
diff --git a/src/buffer/mod.rs b/src/buffer/mod.rs index 10b49c1..0a7e9ba 100644 --- a/src/buffer/mod.rs +++ b/src/buffer/mod.rs @@ -1,23 +1,33 @@ mod threads; +use crate::window::Window; + use std::io::{Stdin, Write}; use termion::event::Key; use termion::input::TermRead; pub use threads::Threads; + pub struct Client { + window: Window, buffers: Vec<Buffer>, } impl Client { - pub fn new(initial_buffer: Buffer) -> Self { + pub fn new<W: Write>(initial_buffer: Buffer, out: &mut W) -> Self { + let mut window = Window::new(); + match &initial_buffer { + Buffer::Threads(t) => t.fill_window(&mut window), + } + window.draw(out).unwrap(); Self { + window, buffers: vec![initial_buffer], } } - pub fn run<W: Write>(mut self, mut screen: W, stdin: Stdin) { + pub fn run<W: Write>(mut self, out: &mut W, stdin: Stdin) { for c in stdin.keys() { let c = c.unwrap(); // Global keybinds @@ -32,12 +42,14 @@ impl Client { } let next_buffer = match self.buffers.last_mut().unwrap() { - Buffer::Threads(s) => s.tick(&mut screen, c), + Buffer::Threads(s) => s.tick(&mut self.window, c), }; if let Some(next_buffer) = next_buffer { self.buffers.push(next_buffer); } + + self.window.draw(out).unwrap(); } } } diff --git a/src/buffer/threads.rs b/src/buffer/threads.rs index 85ffb0f..3525c2a 100644 --- a/src/buffer/threads.rs +++ b/src/buffer/threads.rs @@ -1,9 +1,9 @@ use crate::db; +use crate::window::{Line, Window}; use super::Buffer; use notmuch::DatabaseMode; -use std::io::Write; -use termion::{color, event::Key}; +use termion::event::Key; pub struct Threads { threads: Vec<Thread>, @@ -68,11 +68,21 @@ impl Threads { .collect(); } - pub fn init<W: Write>(&self, out: &mut W) { - self.draw(out); + pub fn fill_window(&self, window: &mut Window) { + println!("filling"); + for (i, thread) in self.threads.iter().enumerate() { + let s = format!("thread: \'{}\' {:?}", thread.subject, thread.authors); + window.lines.push( + if self.i == i { + Line::Highlight(s) + } else { + Line::Normal(s) + } + ); + } } - pub fn tick<W: Write>(&mut self, out: &mut W, key: Key) -> Option<Buffer> { + pub fn tick(&mut self, window: &mut Window, key: Key) -> Option<Buffer> { match key { Key::Char('j') => self.i += 1, Key::Char('k') => self.i = @@ -87,7 +97,7 @@ impl Threads { } Key::Char('s') => { let sent = Threads::from_query(String::from("tag:sent")); - sent.init(out); + sent.fill_window(window); return Some(Buffer::Threads(sent)); } Key::Char('r') => self.reload(), @@ -96,24 +106,7 @@ impl Threads { if !self.threads.is_empty() { self.i = self.i.rem_euclid(self.threads.len()); } - self.draw(out); + self.fill_window(window); None } - - fn draw<W: Write>(&self, out: &mut W) { - write!(out, "{}", termion::clear::All).unwrap(); - - for (i, thread) in self.threads.iter().enumerate() { - write!(out, "{}", termion::cursor::Goto(1, (i + 1) as u16)).unwrap(); - let highlight = i == self.i; - if highlight { - write!(out, "{}", color::Fg(color::Red)).unwrap(); - } - write!(out, "thread {:?}, {:?}", thread.subject, thread.authors).unwrap(); - if highlight { - write!(out, "{}", color::Fg(color::Reset)).unwrap(); - } - } - out.flush().unwrap(); - } } diff --git a/src/main.rs b/src/main.rs index a1a4220..59ed28d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ -mod db; mod buffer; +mod db; +mod window; use crate::buffer::{Client, Buffer}; use crate::buffer::Threads; @@ -16,8 +17,7 @@ fn main() { let mut screen = termion::cursor::HideCursor::from(screen); let threads = Threads::from_query(String::from("tag:inbox")); - threads.init(&mut screen); - let client = Client::new(Buffer::Threads(threads)); - client.run(screen, stdin); + let client = Client::new(Buffer::Threads(threads), &mut screen); + client.run(&mut screen, stdin); } diff --git a/src/window.rs b/src/window.rs new file mode 100644 index 0000000..178c484 --- /dev/null +++ b/src/window.rs @@ -0,0 +1,43 @@ +//! A window is an abstraction for the UI. Buffers (like [Threads]) draw "to" windows. + +use std::io::Write; +use termion::{clear, color, cursor}; + +pub enum Line { + Normal(String), + Highlight(String), +} + +pub struct Window { + pub lines: Vec<Line>, +} + +impl Window { + pub fn new() -> Self { + Self { + lines: Vec::new(), + } + } + + pub fn draw<W: Write>(&mut self, out: &mut W) -> Result<(), std::io::Error> { + write!(out, "{}", clear::All)?; + + for (i, line) in self.lines.iter().enumerate() { + write!(out, "{}", cursor::Goto(1, (i + 1) as u16))?; + match line { + Line::Normal(s) => write!(out, "{}", s)?, + Line::Highlight(s) => write!( + out, + "{}{}{}", + color::Fg(color::Red), + s, + color::Fg(color::Reset), + )?, + } + } + out.flush()?; + + self.lines.clear(); + Ok(()) + } +} |
