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 && let Some(data) = yank_data {
62 register.add_delete(data);
63 }
64
65 ed.cursor.set(cursor);
66 ed.register.set(register);
67
68 CommandExecuted::Yes
69}
70fn handle_move_command_default(
71 ed: &Editor,
72 action: &dyn CommonAction,
73 movement: Movement,
74 count: Option<usize>,
75 modifiers: Modifiers,
76) -> CommandExecuted {
77 ed.last_movement.set(movement.clone());
80
81 let mut cursor = ed.cursor.get_untracked();
82 let modify = modifiers.shift();
83 ed.register.update(|register| {
84 movement::move_cursor(
85 ed,
86 action,
87 &mut cursor,
88 &movement,
89 count.unwrap_or(1),
90 modify,
91 register,
92 )
93 });
94
95 ed.cursor.set(cursor);
96
97 CommandExecuted::Yes
98}
99
100fn handle_scroll_command_default(
101 ed: &Editor,
102 cmd: &ScrollCommand,
103 count: Option<usize>,
104 mods: Modifiers,
105) -> CommandExecuted {
106 match cmd {
107 ScrollCommand::PageUp => {
108 ed.page_move(false, mods);
109 }
110 ScrollCommand::PageDown => {
111 ed.page_move(true, mods);
112 }
113 ScrollCommand::ScrollUp => ed.scroll(0.0, false, count.unwrap_or(1), mods),
114 ScrollCommand::ScrollDown => {
115 ed.scroll(0.0, true, count.unwrap_or(1), mods);
116 }
117 ScrollCommand::CenterOfWindow => {}
119 ScrollCommand::TopOfWindow => {}
120 ScrollCommand::BottomOfWindow => {}
121 }
122
123 CommandExecuted::Yes
124}
125
126fn handle_motion_mode_command_default(
127 ed: &Editor,
128 action: &dyn CommonAction,
129 cmd: &MotionModeCommand,
130 count: Option<usize>,
131) -> CommandExecuted {
132 let count = count.unwrap_or(1);
133 let motion_mode = match cmd {
134 MotionModeCommand::MotionModeDelete => MotionMode::Delete { count },
135 MotionModeCommand::MotionModeIndent => MotionMode::Indent,
136 MotionModeCommand::MotionModeOutdent => MotionMode::Outdent,
137 MotionModeCommand::MotionModeYank => MotionMode::Yank { count },
138 };
139 let mut cursor = ed.cursor.get_untracked();
140 let mut register = ed.register.get_untracked();
141
142 movement::do_motion_mode(ed, action, &mut cursor, motion_mode, &mut register);
143
144 ed.cursor.set(cursor);
145 ed.register.set(register);
146
147 CommandExecuted::Yes
148}
149
150fn handle_multi_selection_command_default(
151 ed: &Editor,
152 cmd: &MultiSelectionCommand,
153) -> CommandExecuted {
154 let mut cursor = ed.cursor.get_untracked();
155 movement::do_multi_selection(ed, &mut cursor, cmd);
156 ed.cursor.set(cursor);
157
158 CommandExecuted::Yes
159}
160
161pub trait CommonAction {
164 fn exec_motion_mode(
166 &self,
167 ed: &Editor,
168 cursor: &mut Cursor,
169 motion_mode: MotionMode,
170 range: Range<usize>,
171 is_vertical: bool,
172 register: &mut Register,
173 );
174
175 fn do_edit(
182 &self,
183 ed: &Editor,
184 cursor: &mut Cursor,
185 cmd: &EditCommand,
186 modal: bool,
187 register: &mut Register,
188 smart_tab: bool,
189 ) -> bool;
190}