mod app;
mod config;
mod editor;
mod highlight;
mod ui;
use app::App;
use config::Config;
use crossterm::event::{
self, Event, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags,
PushKeyboardEnhancementFlags,
};
use crossterm::execute;
use crossterm::terminal::{
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
};
use editor::Buffer;
use ratatui::backend::CrosstermBackend;
use ratatui::Terminal;
use std::io;
use std::time::Duration;
fn main() -> io::Result<()> {
let config = Config::load_or_create();
let buffer = std::env::args()
.nth(1)
.map(std::path::PathBuf::from)
.and_then(|p| Buffer::from_file(p).ok())
.unwrap_or_default();
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen)?;
let supports_keyboard_enhancement = crossterm::terminal::supports_keyboard_enhancement()
.unwrap_or(false);
if supports_keyboard_enhancement {
execute!(
stdout,
PushKeyboardEnhancementFlags(KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES)
)?;
}
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
let mut app = App::new(config, buffer);
let result = run(&mut terminal, &mut app);
if supports_keyboard_enhancement {
execute!(terminal.backend_mut(), PopKeyboardEnhancementFlags)?;
}
disable_raw_mode()?;
execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
terminal.show_cursor()?;
result
}
fn run<B: ratatui::backend::Backend>(terminal: &mut Terminal<B>, app: &mut App) -> io::Result<()> {
loop {
terminal.draw(|frame| ui::draw(frame, app))?;
if event::poll(Duration::from_millis(100))? {
if let Event::Key(key) = event::read()? {
if key.kind == crossterm::event::KeyEventKind::Press {
app.handle_key(key);
}
}
}
if app.should_quit {
return Ok(());
}
}
}