cargo_function_history/
lib.rs1use std::{cell::RefCell, io::stdout, process::exit, rc::Rc, time::Duration};
2
3use crate::app::ui;
4use app::{state::AppState, App, AppReturn};
5use crossterm::event::{self, Event, KeyCode};
6use eyre::Result;
7use keys::Key;
8use tui::{backend::CrosstermBackend, Terminal};
9use tui_input::backend::crossterm as input_backend;
10
11pub mod app;
12pub mod keys;
13pub fn start_ui(app: Rc<RefCell<App>>) -> Result<()> {
14 let stdout = stdout();
16 crossterm::terminal::enable_raw_mode()?;
17 let backend = CrosstermBackend::new(stdout);
18 let mut terminal = Terminal::new(backend)?;
19 terminal.clear()?;
20 terminal.hide_cursor()?;
21 let mut x = false;
22 loop {
23 let mut app = app.borrow_mut();
24
25 terminal.draw(|rect| {
27 if rect.size().width < 15 || rect.size().height < 15 {
29 x = true
30 } else {
31 ui::draw(rect, &mut app)
32 }
33 })?;
34
35 if x {
36 break;
37 }
38 if let Ok(true) = event::poll(Duration::from_millis(100)) {
40 if let Event::Key(key) = event::read()? {
41 match &mut app.state() {
42 AppState::Editing => match key.code {
43 KeyCode::Enter => {
44 app.run_command();
45 app.history_index = app.history.len();
46 app.reset_and_save()
47 }
48 KeyCode::Esc => {
49 app.state = AppState::Looking;
50 }
51 KeyCode::Delete => app.input_buffer.reset(),
52 KeyCode::Up => {
53 app.reset_and_save();
54 app.scroll_up();
55 }
56 KeyCode::Down => {
57 app.reset_and_save();
58 app.scroll_down();
59 }
60 _ => {
61 input_backend::to_input_request(Event::Key(key))
62 .and_then(|req| app.input_buffer.handle(req));
63 }
64 },
65 _ => {
66 let result = app.do_action(Key::from(key));
67 if result == AppReturn::Exit {
69 break;
70 }
71 }
72 }
73 }
74 }
75 }
76
77 terminal.clear()?;
79 terminal.show_cursor()?;
80 crossterm::terminal::disable_raw_mode()?;
81 if x {
82 eprintln!("Not enough space to draw");
83 exit(1)
84 }
85
86 Ok(())
87}