1use std::ops::Range;
2
3use floem_editor_core::{
4 command::{EditCommand, MotionModeCommand, MultiSelectionCommand, ScrollCommand},
5 cursor::Cursor,
6 mode::MotionMode,
7 movement::Movement,
8 register::Register,
9};
10use floem_reactive::{SignalGet, SignalUpdate, SignalWith};
11use ui_events::keyboard::Modifiers;
12
13use super::{
14 Editor,
15 command::{Command, CommandExecuted},
16 movement,
17};
18
19pub fn handle_command_default(
20 ed: &Editor,
21 action: &dyn CommonAction,
22 cmd: &Command,
23 count: Option<usize>,
24 modifiers: Modifiers,
25) -> CommandExecuted {
26 match cmd {
27 Command::Edit(cmd) => handle_edit_command_default(ed, action, cmd),
28 Command::Move(cmd) => {
29 let movement = cmd.to_movement(count);
30 handle_move_command_default(ed, action, movement, count, modifiers)
31 }
32 Command::Scroll(cmd) => handle_scroll_command_default(ed, cmd, count, modifiers),
33 Command::MotionMode(cmd) => handle_motion_mode_command_default(ed, action, cmd, count),
34 Command::MultiSelection(cmd) => handle_multi_selection_command_default(ed, cmd),
35 }
36}
37fn handle_edit_command_default(
38 ed: &Editor,
39 action: &dyn CommonAction,
40 cmd: &EditCommand,
41) -> CommandExecuted {
42 let modal = ed.es.with_untracked(|es| es.modal());
43 let smart_tab = ed.es.with_untracked(|es| es.smart_tab());
44 let mut cursor = ed.cursor.get_untracked();
45 let mut register = ed.register.get_untracked();
46
47 let text = ed.rope_text();
48
49 let yank_data = if let floem_editor_core::cursor::CursorMode::Visual { .. } = &cursor.mode {
50 Some(cursor.yank(&text))
51 } else {
52 None
53 };
54
55 let had_edits = action.do_edit(ed, &mut cursor, cmd, modal, &mut register, smart_tab);
60
61 if had_edits {
62 if let Some(data) = yank_data {
63 register.add_delete(data);
64 }
65 }
66
67 ed.cursor.set(cursor);
68 ed.register.set(register);
69
70 CommandExecuted::Yes
71}
72fn handle_move_command_default(
73 ed: &Editor,
74 action: &dyn CommonAction,
75 movement: Movement,
76 count: Option<usize>,
77 modifiers: Modifiers,
78) -> CommandExecuted {
79 ed.last_movement.set(movement.clone());
82
83 let mut cursor = ed.cursor.get_untracked();
84 let modify = modifiers.shift();
85 ed.register.update(|register| {
86 movement::move_cursor(
87 ed,
88 action,
89 &mut cursor,
90 &movement,
91 count.unwrap_or(1),
92 modify,
93 register,
94 )
95 });
96
97 ed.cursor.set(cursor);
98
99 CommandExecuted::Yes
100}
101
102fn handle_scroll_command_default(
103 ed: &Editor,
104 cmd: &ScrollCommand,
105 count: Option<usize>,
106 mods: Modifiers,
107) -> CommandExecuted {
108 match cmd {
109 ScrollCommand::PageUp => {
110 ed.page_move(false, mods);
111 }
112 ScrollCommand::PageDown => {
113 ed.page_move(true, mods);
114 }
115 ScrollCommand::ScrollUp => ed.scroll(0.0, false, count.unwrap_or(1), mods),
116 ScrollCommand::ScrollDown => {
117 ed.scroll(0.0, true, count.unwrap_or(1), mods);
118 }
119 ScrollCommand::CenterOfWindow => {}
121 ScrollCommand::TopOfWindow => {}
122 ScrollCommand::BottomOfWindow => {}
123 }
124
125 CommandExecuted::Yes
126}
127
128fn handle_motion_mode_command_default(
129 ed: &Editor,
130 action: &dyn CommonAction,
131 cmd: &MotionModeCommand,
132 count: Option<usize>,
133) -> CommandExecuted {
134 let count = count.unwrap_or(1);
135 let motion_mode = match cmd {
136 MotionModeCommand::MotionModeDelete => MotionMode::Delete { count },
137 MotionModeCommand::MotionModeIndent => MotionMode::Indent,
138 MotionModeCommand::MotionModeOutdent => MotionMode::Outdent,
139 MotionModeCommand::MotionModeYank => MotionMode::Yank { count },
140 };
141 let mut cursor = ed.cursor.get_untracked();
142 let mut register = ed.register.get_untracked();
143
144 movement::do_motion_mode(ed, action, &mut cursor, motion_mode, &mut register);
145
146 ed.cursor.set(cursor);
147 ed.register.set(register);
148
149 CommandExecuted::Yes
150}
151
152fn handle_multi_selection_command_default(
153 ed: &Editor,
154 cmd: &MultiSelectionCommand,
155) -> CommandExecuted {
156 let mut cursor = ed.cursor.get_untracked();
157 movement::do_multi_selection(ed, &mut cursor, cmd);
158 ed.cursor.set(cursor);
159
160 CommandExecuted::Yes
161}
162
163pub trait CommonAction {
166 fn exec_motion_mode(
168 &self,
169 ed: &Editor,
170 cursor: &mut Cursor,
171 motion_mode: MotionMode,
172 range: Range<usize>,
173 is_vertical: bool,
174 register: &mut Register,
175 );
176
177 fn do_edit(
184 &self,
185 ed: &Editor,
186 cursor: &mut Cursor,
187 cmd: &EditCommand,
188 modal: bool,
189 register: &mut Register,
190 smart_tab: bool,
191 ) -> bool;
192}