git_iblame/
cli.rs

1use std::{io::stdout, path::Path};
2
3use crate::*;
4use crossterm::{clipboard::CopyToClipboard, execute, terminal};
5
6pub struct Cli {
7    renderer: BlameRenderer,
8}
9
10impl Cli {
11    pub fn new(path: &Path) -> anyhow::Result<Self> {
12        Ok(Self {
13            renderer: BlameRenderer::new(path)?,
14        })
15    }
16
17    pub fn run(&mut self) -> anyhow::Result<()> {
18        let renderer = &mut self.renderer;
19        let size = terminal::size()?;
20        renderer.set_size((size.0, size.1 - 1));
21        renderer.read_file()?;
22        let mut out = stdout();
23        loop {
24            renderer.render(&mut out)?;
25            let command = Command::read(renderer.rendered_rows())?;
26            match command {
27                Command::PrevDiff => renderer.move_to_prev_diff(),
28                Command::NextDiff => renderer.move_to_next_diff(),
29                Command::PageUp => renderer.move_to_prev_page(),
30                Command::PageDown => renderer.move_to_next_page(),
31                Command::FirstLine => renderer.move_to_first_line(),
32                Command::LastLine => renderer.move_to_last_line(),
33                Command::LineNumber(number) => renderer.set_current_number(number),
34                Command::Deep => renderer.set_newest_commit_id_to_older()?,
35                Command::Copy => execute!(
36                    out,
37                    CopyToClipboard::to_clipboard_from(renderer.current_commit_id().to_string())
38                )?,
39                Command::Resize(columns, rows) => renderer.set_size((columns, rows - 1)),
40                Command::Quit => break,
41            }
42        }
43        Ok(())
44    }
45}