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}