indigo_core/mode/
replace.rs1#![allow(clippy::enum_glob_use)]
2
3use crate::{
4 editor::Editor,
5 key::{KeyCode, KeyModifiers},
6 keymap::{Keymap, KeymapResult, keymap},
7 mode::{Mode, normal},
8};
9use std::sync::LazyLock;
10
11#[cfg(feature = "arbitrary")]
12use arbitrary::Arbitrary;
13
14#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
15#[derive(Debug)]
16pub enum Action {
17 Replace(u8),
18}
19
20pub static KEYMAP: LazyLock<Keymap<Vec<Action>>> = LazyLock::new(|| {
21 use Action::*;
22 keymap! { Vec<Action>;
23 "<esc>" => vec![], "<ret>" => vec![Replace(b'\n')], "<tab>" => vec![Replace(b'\t')], keys => {
27 if let [key] = keys
28 && let KeyCode::Char(c) = key.code
29 && key.modifiers.difference(KeyModifiers::SHIFT).is_empty()
30 {
31 KeymapResult::Fallback(vec![Replace(c)])
32 } else {
33 KeymapResult::Unmapped
34 }
35 } }
37});
38
39pub fn handle_actions(editor: &mut Editor, actions: &[Action]) {
40 for action in actions {
41 handle_action(editor, action);
42 }
43}
44
45pub fn handle_action(editor: &mut Editor, action: &Action) {
46 match action {
47 Action::Replace(byte) => replace(editor, *byte),
48 }
49}
50
51pub fn handle_keys(editor: &mut Editor) -> bool {
52 match KEYMAP.get_keys(&editor.pending_keys) {
53 KeymapResult::Mapped(actions) => {
54 editor.pending_keys.clear();
55 handle_actions(editor, actions);
56 normal::enter(editor);
57 }
58 KeymapResult::Fallback(actions) => {
59 editor.pending_keys.clear();
60 handle_actions(editor, &actions);
61 normal::enter(editor);
62 }
63 KeymapResult::Unmapped => {
64 editor.pending_keys.clear();
65 normal::enter(editor);
66 }
67 KeymapResult::Pending => {}
68 }
69
70 true
71}
72
73pub fn enter(editor: &mut Editor) {
74 editor.mode = Mode::Replace;
75}
76
77fn replace(editor: &mut Editor, byte: u8) {
78 if editor.focused_buffer().text.readonly {
79 editor.message = Some(Err(String::from("Buffer is readonly")));
80 editor.count = None;
81 return;
82 }
83 let mut window = editor.focused_window_mut();
84 window.selection_edit().replace_each(byte);
85 window.scroll_to_selection();
86 editor.count = None;
87}