use std::error::Error; use edtui::{EditorEventHandler, EditorState, EditorView, SyntaxHighlighter}; use ratatui::crossterm::event::{self, Event, KeyCode, KeyModifiers}; use ratatui::{prelude::*, widgets::Widget}; use crate::term::Term; use crate::theme::Theme; pub type Result = std::result::Result>; #[derive(Default)] pub struct App { pub context: AppContext, pub should_quit: bool, } #[derive(Default)] pub struct AppContext { pub state: EditorState, pub event_handler: EditorEventHandler, } impl App { pub fn run(&mut self, term: &mut Term) -> Result<()> { while !self.should_quit { self.draw(term)?; self.handle_events()?; } Term::stop()?; Ok(()) } pub fn draw(&mut self, term: &mut Term) -> Result<()> { let _ = term.draw(|f| f.render_widget(self, f.area())); Ok(()) } pub fn handle_events(&mut self) -> Result<()> { let event = event::read()?; if let Event::Key(key) = event { if key.code == KeyCode::Char('c') && key.modifiers == KeyModifiers::CONTROL { self.should_quit = true; return Ok(()); } }; self.context .event_handler .on_event(event, &mut self.context.state); Ok(()) } } impl Widget for &mut App { fn render(self, area: Rect, buf: &mut Buffer) { let syntax_highlighter = SyntaxHighlighter::new("dracula", "rs"); EditorView::new(&mut self.context.state) .wrap(true) .theme(Theme::new().editor) .syntax_highlighter(Some(syntax_highlighter)) .render(area, buf) } }