sl_up/
ui.rs

1use std::io::{self, Stdout, Write};
2
3use crossterm::{
4    cursor::{Hide, MoveTo, Show},
5    event::{Event, KeyCode},
6    terminal::{self, Clear, ClearType, EnterAlternateScreen, LeaveAlternateScreen},
7    ExecutableCommand, QueueableCommand,
8};
9
10use crate::smartlog::SmartLog;
11
12pub fn start_ui_and_get_selected_commit<'a>(smartlog: &'a mut SmartLog) -> Option<&'a str> {
13    let mut stdout = io::stdout();
14    terminal::enable_raw_mode().unwrap();
15    stdout.execute(EnterAlternateScreen).unwrap();
16    stdout.execute(Hide).unwrap();
17    render_smartlog(&mut stdout, smartlog);
18
19    let mut commit_hash: Option<&str> = None;
20    'terminal_ui: loop {
21        let input = crossterm::event::read().unwrap();
22        if let Event::Key(key_event) = input {
23            match key_event.code {
24                KeyCode::Char('q') | KeyCode::Esc => break 'terminal_ui,
25                KeyCode::Char('c') => {
26                    if key_event
27                        .modifiers
28                        .contains(crossterm::event::KeyModifiers::CONTROL)
29                    {
30                        break 'terminal_ui;
31                    }
32                }
33                KeyCode::Up => {
34                    smartlog.move_up();
35                }
36                KeyCode::Down => {
37                    smartlog.move_down();
38                }
39                KeyCode::Char(' ') | KeyCode::Enter => {
40                    commit_hash = Some(smartlog.get_selected_commit_hash().unwrap());
41                    break 'terminal_ui;
42                }
43                _ => {}
44            }
45        }
46        render_smartlog(&mut stdout, smartlog);
47    }
48
49    // Cleanup
50    stdout.execute(Show).unwrap();
51    stdout.execute(LeaveAlternateScreen).unwrap();
52    terminal::disable_raw_mode().unwrap();
53
54    commit_hash
55}
56
57fn render_smartlog(stdout: &mut Stdout, smartlog: &SmartLog) {
58    stdout.queue(Clear(ClearType::All)).unwrap();
59    for (idx, line) in smartlog.to_string_vec().iter().enumerate() {
60        stdout.queue(MoveTo(0_u16, idx as u16)).unwrap();
61        print!("{}", *line);
62    }
63    stdout.flush().unwrap();
64}