From 2d1c367f7754a495cb0caf05779e21ce7ba60354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Wed, 28 Apr 2021 23:53:28 +0200 Subject: state -> buffer --- src/buffer/mod.rs | 47 +++++++++++++++++++++ src/buffer/threads.rs | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 8 ++-- src/state/mod.rs | 47 --------------------- src/state/threads.rs | 114 -------------------------------------------------- 5 files changed, 165 insertions(+), 165 deletions(-) create mode 100644 src/buffer/mod.rs create mode 100644 src/buffer/threads.rs delete mode 100644 src/state/mod.rs delete mode 100644 src/state/threads.rs (limited to 'src') diff --git a/src/buffer/mod.rs b/src/buffer/mod.rs new file mode 100644 index 0000000..fe83a97 --- /dev/null +++ b/src/buffer/mod.rs @@ -0,0 +1,47 @@ +mod threads; + +use std::io::{Stdin, Write}; +use termion::event::Key; +use termion::input::TermRead; + +pub use threads::Threads; + +pub struct Client { + buffers: Vec, +} + +impl Client { + pub fn new(initial_buffer: Buffer) -> Self { + Self { + buffers: vec![initial_buffer], + } + } + + pub fn run(mut self, mut screen: W, stdin: Stdin) { + for c in stdin.keys() { + let c = c.unwrap(); + // Global keybinds + match c { + Key::Char('q') => { + self.buffers.pop().unwrap(); + if self.buffers.is_empty() { + break; + } + }, + _ => () + } + + let next_buffer = match self.buffers.last_mut().unwrap() { + Buffer::Threads(s) => s.tick(&mut screen, c), + }; + + if let Some(next_buffer) = next_buffer { + self.buffers.push(next_buffer); + } + } + } +} + +pub enum Buffer { + Threads(Threads), +} diff --git a/src/buffer/threads.rs b/src/buffer/threads.rs new file mode 100644 index 0000000..ddef067 --- /dev/null +++ b/src/buffer/threads.rs @@ -0,0 +1,114 @@ +use crate::db; +use super::Buffer; + +use notmuch::DatabaseMode; +use std::io::Write; +use termion::{color, event::Key}; + +pub struct Threads { + threads: Vec, + i: usize, + + query: String, +} + +pub struct Thread { + subject: String, + authors: Vec, + _id: String, + messages: Vec, +} + +impl<'d, 'q> Thread { + pub fn new(thread: notmuch::Thread<'d, 'q>) -> Self { + Self { + subject: thread.subject().to_string(), + authors: thread.authors().clone(), + _id: thread.id().to_string(), + messages: thread.messages().map(|m| m.id().to_string()).collect(), + } + } + + pub fn remove_tag(&self, tag: &str) { + let db = db::open(DatabaseMode::ReadWrite).unwrap(); + for m_id in self.messages.iter() { + db + .find_message(m_id) + .unwrap() + .unwrap() + .remove_tag(tag) + .unwrap(); + } + } +} + +impl Threads { + pub fn from_query(query: String) -> Self { + let mut res = Self { + threads: Vec::new(), + i: 0, + query, + }; + res.reload(); + res + } + + pub fn reload(&mut self) { + self.threads = db::open(DatabaseMode::ReadOnly) + .unwrap() + .create_query(&self.query) + .unwrap() + .search_threads() + .unwrap() + .map(Thread::new) + .collect(); + } + + pub fn init(&self, out: &mut W) { + self.draw(out); + } + + pub fn tick(&mut self, out: &mut W, key: Key) -> Option { + match key { + Key::Char('j') => self.i += 1, + Key::Char('k') => self.i = + if self.i == 0 { + self.threads.len() + } else { + self.i - 1 + }, + Key::Char('i') => { + self.threads[self.i].remove_tag("inbox"); + } + Key::Char('s') => { + let sent = Threads::from_query(String::from("tag:sent")); + sent.init(out); + return Some(Buffer::Threads(sent)); + } + Key::Char('r') => self.reload(), + _ => (), + } + if !self.threads.is_empty() { + self.i = self.i.rem_euclid(self.threads.len()); + } + self.draw(out); + None + } + + fn draw(&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 58c084e..a1a4220 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,8 @@ mod db; -mod state; +mod buffer; -use crate::state::{Client, State}; -use crate::state::Threads; +use crate::buffer::{Client, Buffer}; +use crate::buffer::Threads; use std::io::{stdin, stdout}; use termion::raw::IntoRawMode; @@ -18,6 +18,6 @@ fn main() { let threads = Threads::from_query(String::from("tag:inbox")); threads.init(&mut screen); - let client = Client::new(State::Threads(threads)); + let client = Client::new(Buffer::Threads(threads)); client.run(screen, stdin); } diff --git a/src/state/mod.rs b/src/state/mod.rs deleted file mode 100644 index 0fe9f40..0000000 --- a/src/state/mod.rs +++ /dev/null @@ -1,47 +0,0 @@ -mod threads; - -use std::io::{Stdin, Write}; -use termion::event::Key; -use termion::input::TermRead; - -pub use threads::Threads; - -pub struct Client { - states: Vec, -} - -impl Client { - pub fn new(initial_state: State) -> Self { - Self { - states: vec![initial_state], - } - } - - pub fn run(mut self, mut screen: W, stdin: Stdin) { - for c in stdin.keys() { - let c = c.unwrap(); - // Global keybinds - match c { - Key::Char('q') => { - self.states.pop().unwrap(); - if self.states.is_empty() { - break; - } - }, - _ => () - } - - let next_state = match self.states.last_mut().unwrap() { - State::Threads(s) => s.tick(&mut screen, c), - }; - - if let Some(next_state) = next_state { - self.states.push(next_state); - } - } - } -} - -pub enum State { - Threads(Threads), -} diff --git a/src/state/threads.rs b/src/state/threads.rs deleted file mode 100644 index be566e5..0000000 --- a/src/state/threads.rs +++ /dev/null @@ -1,114 +0,0 @@ -use crate::db; -use super::State; - -use notmuch::DatabaseMode; -use std::io::Write; -use termion::{color, event::Key}; - -pub struct Threads { - threads: Vec, - i: usize, - - query: String, -} - -pub struct Thread { - subject: String, - authors: Vec, - _id: String, - messages: Vec, -} - -impl<'d, 'q> Thread { - pub fn new(thread: notmuch::Thread<'d, 'q>) -> Self { - Self { - subject: thread.subject().to_string(), - authors: thread.authors().clone(), - _id: thread.id().to_string(), - messages: thread.messages().map(|m| m.id().to_string()).collect(), - } - } - - pub fn remove_tag(&self, tag: &str) { - let db = db::open(DatabaseMode::ReadWrite).unwrap(); - for m_id in self.messages.iter() { - db - .find_message(m_id) - .unwrap() - .unwrap() - .remove_tag(tag) - .unwrap(); - } - } -} - -impl Threads { - pub fn from_query(query: String) -> Self { - let mut res = Self { - threads: Vec::new(), - i: 0, - query, - }; - res.reload(); - res - } - - pub fn reload(&mut self) { - self.threads = db::open(DatabaseMode::ReadOnly) - .unwrap() - .create_query(&self.query) - .unwrap() - .search_threads() - .unwrap() - .map(Thread::new) - .collect(); - } - - pub fn init(&self, out: &mut W) { - draw(&self, out); - } - - pub fn tick(&mut self, out: &mut W, key: Key) -> Option { - match key { - Key::Char('j') => self.i += 1, - Key::Char('k') => self.i = - if self.i == 0 { - self.threads.len() - } else { - self.i - 1 - }, - Key::Char('i') => { - self.threads[self.i].remove_tag("inbox"); - } - Key::Char('s') => { - let sent = Threads::from_query(String::from("tag:sent")); - sent.init(out); - return Some(State::Threads(sent)); - } - Key::Char('r') => self.reload(), - _ => (), - } - if !self.threads.is_empty() { - self.i = self.i.rem_euclid(self.threads.len()); - } - draw(&self, out); - None - } -} - -fn draw(state: &Threads, out: &mut W) { - write!(out, "{}", termion::clear::All).unwrap(); - - for (i, thread) in state.threads.iter().enumerate() { - write!(out, "{}", termion::cursor::Goto(1, (i + 1) as u16)).unwrap(); - let highlight = i == state.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(); -} -- cgit v1.2.1