duat_utils/modes/
regular.rs

1use duat_core::{
2    data::Pass,
3    file::File,
4    mode::{self, KeyCode::*, KeyEvent, KeyMod as Mod, key},
5    prelude::Handle,
6    ui::Ui,
7};
8
9use super::{IncSearch, RunCommands, SearchFwd, SearchRev};
10
11/// The regular, bogstandard mode, a.k.a., supposed to be like VSCode
12#[derive(Clone)]
13pub struct Regular;
14
15impl<U: Ui> mode::Mode<U> for Regular {
16    type Widget = File<U>;
17
18    fn send_key(&mut self, pa: &mut Pass, key: KeyEvent, handle: Handle<Self::Widget, U>) {
19        match key {
20            // Characters
21            key!(Char(char)) => handle.edit_all(pa, |mut e| {
22                e.insert(char);
23                e.move_hor(1);
24            }),
25            key!(Enter) => handle.edit_all(pa, |mut e| {
26                e.insert('\n');
27                e.move_hor(1);
28            }),
29
30            // Text Removal
31            key!(Backspace) => handle.edit_all(pa, |mut e| {
32                if e.anchor().is_some() {
33                    e.replace("");
34                    e.unset_anchor();
35                } else {
36                    e.move_hor(-1);
37                    e.set_anchor();
38                    e.replace("");
39                    e.unset_anchor();
40                }
41            }),
42            key!(Delete) => handle.edit_all(pa, |mut e| {
43                e.set_anchor_if_needed();
44                e.replace("");
45                e.unset_anchor();
46            }),
47
48            // Movement
49            key!(Left) => handle.edit_all(pa, |mut e| {
50                e.unset_anchor();
51                e.move_hor(-1);
52            }),
53            key!(Right) => handle.edit_all(pa, |mut e| {
54                e.unset_anchor();
55                e.move_hor(1);
56            }),
57            key!(Up) => handle.edit_all(pa, |mut e| {
58                e.unset_anchor();
59                e.move_ver(-1);
60            }),
61            key!(Down) => handle.edit_all(pa, |mut e| {
62                e.unset_anchor();
63                e.move_ver(1);
64            }),
65            key!(Left, Mod::SHIFT) => handle.edit_all(pa, |mut e| {
66                e.set_anchor_if_needed();
67                e.move_hor(-1);
68            }),
69            key!(Right, Mod::SHIFT) => handle.edit_all(pa, |mut e| {
70                e.set_anchor_if_needed();
71                e.move_hor(1);
72            }),
73            key!(Up, Mod::SHIFT) => handle.edit_all(pa, |mut e| {
74                e.set_anchor_if_needed();
75                e.move_ver(-1);
76            }),
77            key!(Down, Mod::SHIFT) => handle.edit_all(pa, |mut e| {
78                e.set_anchor_if_needed();
79                e.move_ver(1);
80            }),
81
82            // Copying and pasting
83            key!(Char('c'), Mod::CONTROL) => handle.edit_main(pa, |e| {
84                duat_core::clipboard::set_text(e.selection());
85            }),
86            key!(Char('v'), Mod::CONTROL) => handle.edit_all(pa, |mut e| {
87                if let Some(text) = duat_core::clipboard::get_text() {
88                    e.replace(text);
89                }
90            }),
91
92            // Control
93            key!(Char('p'), Mod::CONTROL) => mode::set::<U>(RunCommands::new()),
94            key!(Char('f'), Mod::CONTROL) => mode::set::<U>(IncSearch::new(SearchFwd)),
95            key!(Char('F'), Mod::CONTROL) => mode::set::<U>(IncSearch::new(SearchRev)),
96
97            _ => {}
98        }
99    }
100}