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}