Skip to main content

editor/
editor.rs

1use crossterm::{
2    event::{
3        self, DisableMouseCapture, EnableMouseCapture, 
4        Event, KeyCode, KeyModifiers, KeyEvent
5    },
6    execute,
7    terminal::{
8        EnterAlternateScreen, LeaveAlternateScreen, 
9        disable_raw_mode, enable_raw_mode
10    },
11};
12use ratatui::{Terminal, backend::CrosstermBackend, layout::Position};
13use std::io::stdout;
14use ratatui_code_editor::editor::Editor;
15use ratatui_code_editor::theme::vesper;
16use ratatui_code_editor::utils::get_lang;
17
18fn main() -> anyhow::Result<()> {
19    let args: Vec<String> = std::env::args().collect();
20    
21    let filename = if args.len() > 1 {
22        &args[1]
23    } else {
24        eprintln!("Usage: cargo run --release --example editor <filename>");
25        return Ok(());
26    };
27    
28    let language = get_lang(filename);
29    let content = std::fs::read_to_string(filename)?;
30
31    enable_raw_mode()?;
32    execute!(stdout(), EnterAlternateScreen)?;
33    execute!(stdout(), EnableMouseCapture)?;
34
35    let backend = CrosstermBackend::new(stdout());
36    let mut terminal = Terminal::new(backend)?;
37    
38    let theme = vesper();
39
40    let mut editor = Editor::new(&language, &content, theme)?;
41    let mut editor_area = ratatui::layout::Rect::default(); 
42
43    loop {
44
45        terminal.draw(|f| {
46            let area = f.area();
47            editor_area = area;
48            f.render_widget(&editor, area);
49            
50            let cursor = editor.get_visible_cursor(&area);
51            if let Some((x,y)) = cursor {
52                f.set_cursor_position(Position::new(x, y));
53            }
54        })?;
55
56        if event::poll(std::time::Duration::from_millis(100))? {
57            match event::read()? {
58                Event::Key(key) => {
59                    if key.code == KeyCode::Esc {
60                        break;
61                    } else if is_save_pressed(key) {
62                        let content = editor.get_content();
63                        save_to_file(&content, filename)?;
64                    } else {
65                        editor.input(key, &editor_area)?;
66                    }
67                }
68                Event::Mouse(mouse) => {
69                    editor.mouse(mouse, &editor_area)?;
70                },
71                Event::Resize(_, _) => { }
72                _ => {}
73            }
74        }
75    }
76
77    disable_raw_mode()?;
78    execute!(
79        terminal.backend_mut(),
80        LeaveAlternateScreen,
81        DisableMouseCapture
82    )?;
83    Ok(())
84}
85
86fn save_to_file(content: &str, path: &str) -> anyhow::Result<()> {
87    use std::io::Write;
88    
89    let mut file = std::fs::File::create(path)?;
90    file.write_all(content.as_bytes())?;
91    Ok(())
92}
93
94fn is_save_pressed(key: KeyEvent) -> bool {
95    key.modifiers.contains(KeyModifiers::CONTROL) &&
96        key.code == KeyCode::Char('s')
97}