pub struct Editor { /* private fields */ }Implementations§
Source§impl Editor
impl Editor
Sourcepub fn new(id: impl Into<ElementId>, lines: Vec<String>) -> Self
pub fn new(id: impl Into<ElementId>, lines: Vec<String>) -> Self
Examples found in repository?
examples/editor_demo.rs (line 71)
47 fn new(cx: &mut Context<Self>) -> Self {
48 let focus_handle = cx.focus_handle();
49
50 let initial_code = vec![
51 "// Rust sample code".to_string(),
52 "use std::collections::HashMap;".to_string(),
53 "".to_string(),
54 "fn main() {".to_string(),
55 " let mut count = 0;".to_string(),
56 " ".to_string(),
57 " // Count from 1 to 10".to_string(),
58 " for i in 1..=10 {".to_string(),
59 " count += i;".to_string(),
60 " }".to_string(),
61 " ".to_string(),
62 " // HashMap example".to_string(),
63 " let mut scores = HashMap::new();".to_string(),
64 " scores.insert(\"Blue\", 10);".to_string(),
65 " scores.insert(\"Yellow\", 50);".to_string(),
66 " ".to_string(),
67 " println!(\"Final count: {}\", count);".to_string(),
68 "}".to_string(),
69 ];
70
71 let mut editor = Editor::new("editor", initial_code);
72
73 let highlighter = SyntaxHighlighter::new();
74 let available_themes = highlighter.available_themes();
75
76 let default_theme_index = available_themes
77 .iter()
78 .position(|t| t == "base16-ocean.dark")
79 .unwrap_or(0);
80
81 editor.set_theme(&available_themes[default_theme_index]);
82
83 let available_languages = vec![
84 ("Rust".to_string(), "rs".to_string(), get_rust_sample()),
85 (
86 "Plain Text".to_string(),
87 "txt".to_string(),
88 get_plain_text_sample(),
89 ),
90 ];
91
92 editor.set_language("Rust".to_string());
93
94 Self {
95 focus_handle,
96 editor,
97 current_theme_index: default_theme_index,
98 available_themes,
99 current_language_index: 0,
100 available_languages,
101 }
102 }pub fn id(&self) -> &ElementId
pub fn config(&self) -> &EditorConfig
pub fn config_mut(&mut self) -> &mut EditorConfig
pub fn set_config(&mut self, config: EditorConfig)
Sourcepub fn cursor_position(&self) -> CursorPosition
pub fn cursor_position(&self) -> CursorPosition
Examples found in repository?
examples/editor_demo.rs (line 286)
277 fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
278 let _current_theme = &self.available_themes[self.current_theme_index];
279 let (current_language, _, _) = &self.available_languages[self.current_language_index];
280
281 let language = match current_language.as_str() {
282 "Rust" => Language::Rust,
283 _ => Language::PlainText,
284 };
285
286 let cursor_position = self.editor.cursor_position();
287 let cursor_point = Point::new(cursor_position.col, cursor_position.row);
288
289 let selection = if self.editor.has_selection() {
290 let selected_text = self.get_selected_text();
291 Some(Selection {
292 lines: selected_text.matches('\n').count(),
293 chars: selected_text.len(),
294 })
295 } else {
296 None
297 };
298
299 div()
300 .key_context("editor")
301 .size_full()
302 .flex()
303 .flex_col()
304 .child(
305 div()
306 .flex_grow()
307 .track_focus(&self.focus_handle)
308 .on_action(cx.listener(Self::move_up))
309 .on_action(cx.listener(Self::move_down))
310 .on_action(cx.listener(Self::move_left))
311 .on_action(cx.listener(Self::move_right))
312 .on_action(cx.listener(Self::move_up_with_shift))
313 .on_action(cx.listener(Self::move_down_with_shift))
314 .on_action(cx.listener(Self::move_left_with_shift))
315 .on_action(cx.listener(Self::move_right_with_shift))
316 .on_action(cx.listener(Self::backspace))
317 .on_action(cx.listener(Self::delete))
318 .on_action(cx.listener(Self::insert_newline))
319 .on_action(cx.listener(Self::select_all))
320 .on_action(cx.listener(Self::escape))
321 .on_action(cx.listener(Self::copy))
322 .on_action(cx.listener(Self::cut))
323 .on_action(cx.listener(Self::paste))
324 .on_action(cx.listener(Self::next_theme))
325 .on_action(cx.listener(Self::previous_theme))
326 .on_action(cx.listener(Self::next_language))
327 .on_action(cx.listener(Self::previous_language))
328 .on_key_down(cx.listener(
329 |this: &mut Self, event: &KeyDownEvent, _window, cx| {
330 // Handle character input
331 if let Some(text) = &event.keystroke.key_char {
332 if !event.keystroke.modifiers.platform
333 && !event.keystroke.modifiers.control
334 && !event.keystroke.modifiers.function
335 {
336 for ch in text.chars() {
337 this.editor.insert_char(ch);
338 }
339 cx.notify();
340 }
341 }
342 },
343 ))
344 .child(EditorElement::new(self.editor.clone())),
345 )
346 .child(MetaLine::new(cursor_point, language, selection))
347 }pub fn set_cursor_position(&mut self, position: CursorPosition)
pub fn get_cursor_position(&self) -> CursorPosition
Sourcepub fn clear_selection(&mut self)
pub fn clear_selection(&mut self)
pub fn get_buffer(&self) -> &GapBuffer
pub fn get_buffer_mut(&mut self) -> &mut GapBuffer
pub fn language(&self) -> &str
Sourcepub fn set_language(&mut self, language: String)
pub fn set_language(&mut self, language: String)
Examples found in repository?
examples/editor_demo.rs (line 92)
47 fn new(cx: &mut Context<Self>) -> Self {
48 let focus_handle = cx.focus_handle();
49
50 let initial_code = vec![
51 "// Rust sample code".to_string(),
52 "use std::collections::HashMap;".to_string(),
53 "".to_string(),
54 "fn main() {".to_string(),
55 " let mut count = 0;".to_string(),
56 " ".to_string(),
57 " // Count from 1 to 10".to_string(),
58 " for i in 1..=10 {".to_string(),
59 " count += i;".to_string(),
60 " }".to_string(),
61 " ".to_string(),
62 " // HashMap example".to_string(),
63 " let mut scores = HashMap::new();".to_string(),
64 " scores.insert(\"Blue\", 10);".to_string(),
65 " scores.insert(\"Yellow\", 50);".to_string(),
66 " ".to_string(),
67 " println!(\"Final count: {}\", count);".to_string(),
68 "}".to_string(),
69 ];
70
71 let mut editor = Editor::new("editor", initial_code);
72
73 let highlighter = SyntaxHighlighter::new();
74 let available_themes = highlighter.available_themes();
75
76 let default_theme_index = available_themes
77 .iter()
78 .position(|t| t == "base16-ocean.dark")
79 .unwrap_or(0);
80
81 editor.set_theme(&available_themes[default_theme_index]);
82
83 let available_languages = vec![
84 ("Rust".to_string(), "rs".to_string(), get_rust_sample()),
85 (
86 "Plain Text".to_string(),
87 "txt".to_string(),
88 get_plain_text_sample(),
89 ),
90 ];
91
92 editor.set_language("Rust".to_string());
93
94 Self {
95 focus_handle,
96 editor,
97 current_theme_index: default_theme_index,
98 available_themes,
99 current_language_index: 0,
100 available_languages,
101 }
102 }
103
104 fn get_selected_text(&self) -> String {
105 self.editor.get_selected_text()
106 }
107
108 // Action handlers
109 fn move_up(&mut self, _: &MoveUp, _window: &mut Window, cx: &mut Context<Self>) {
110 self.editor.move_up(false);
111 cx.notify();
112 }
113
114 fn move_down(&mut self, _: &MoveDown, _window: &mut Window, cx: &mut Context<Self>) {
115 self.editor.move_down(false);
116 cx.notify();
117 }
118
119 fn move_left(&mut self, _: &MoveLeft, _window: &mut Window, cx: &mut Context<Self>) {
120 self.editor.move_left(false);
121 cx.notify();
122 }
123
124 fn move_right(&mut self, _: &MoveRight, _window: &mut Window, cx: &mut Context<Self>) {
125 self.editor.move_right(false);
126 cx.notify();
127 }
128
129 fn move_up_with_shift(
130 &mut self,
131 _: &MoveUpWithShift,
132 _window: &mut Window,
133 cx: &mut Context<Self>,
134 ) {
135 self.editor.move_up(true);
136 cx.notify();
137 }
138
139 fn move_down_with_shift(
140 &mut self,
141 _: &MoveDownWithShift,
142 _window: &mut Window,
143 cx: &mut Context<Self>,
144 ) {
145 self.editor.move_down(true);
146 cx.notify();
147 }
148
149 fn move_left_with_shift(
150 &mut self,
151 _: &MoveLeftWithShift,
152 _window: &mut Window,
153 cx: &mut Context<Self>,
154 ) {
155 self.editor.move_left(true);
156 cx.notify();
157 }
158
159 fn move_right_with_shift(
160 &mut self,
161 _: &MoveRightWithShift,
162 _window: &mut Window,
163 cx: &mut Context<Self>,
164 ) {
165 self.editor.move_right(true);
166 cx.notify();
167 }
168
169 fn backspace(&mut self, _: &Backspace, _window: &mut Window, cx: &mut Context<Self>) {
170 self.editor.backspace();
171 cx.notify();
172 }
173
174 fn delete(&mut self, _: &Delete, _window: &mut Window, cx: &mut Context<Self>) {
175 self.editor.delete();
176 cx.notify();
177 }
178
179 fn insert_newline(&mut self, _: &InsertNewline, _window: &mut Window, cx: &mut Context<Self>) {
180 self.editor.insert_newline();
181 cx.notify();
182 }
183
184 fn select_all(&mut self, _: &SelectAll, _window: &mut Window, cx: &mut Context<Self>) {
185 self.editor.select_all();
186 cx.notify();
187 }
188
189 fn escape(&mut self, _: &Escape, _window: &mut Window, cx: &mut Context<Self>) {
190 self.editor.clear_selection();
191 cx.notify();
192 }
193
194 fn copy(&mut self, _: &Copy, _window: &mut Window, cx: &mut Context<Self>) {
195 let selected_text = self.get_selected_text();
196 if !selected_text.is_empty() {
197 cx.write_to_clipboard(ClipboardItem::new_string(selected_text));
198 }
199 }
200
201 fn cut(&mut self, _: &Cut, _window: &mut Window, cx: &mut Context<Self>) {
202 let selected_text = self.get_selected_text();
203 if !selected_text.is_empty() {
204 cx.write_to_clipboard(ClipboardItem::new_string(selected_text));
205 self.editor.delete_selection();
206 cx.notify();
207 }
208 }
209
210 fn paste(&mut self, _: &Paste, _window: &mut Window, cx: &mut Context<Self>) {
211 if let Some(clipboard) = cx.read_from_clipboard() {
212 if let Some(text) = clipboard.text() {
213 // Delete selection if exists
214 self.editor.delete_selection();
215
216 // Insert text character by character (simplified)
217 for ch in text.chars() {
218 if ch == '\n' {
219 self.editor.insert_newline();
220 } else if ch != '\r' {
221 self.editor.insert_char(ch);
222 }
223 }
224 cx.notify();
225 }
226 }
227 }
228
229 fn next_theme(&mut self, _: &NextTheme, _window: &mut Window, cx: &mut Context<Self>) {
230 self.current_theme_index = (self.current_theme_index + 1) % self.available_themes.len();
231 self.editor
232 .set_theme(&self.available_themes[self.current_theme_index]);
233 cx.notify();
234 }
235
236 fn previous_theme(&mut self, _: &PreviousTheme, _window: &mut Window, cx: &mut Context<Self>) {
237 self.current_theme_index = if self.current_theme_index == 0 {
238 self.available_themes.len() - 1
239 } else {
240 self.current_theme_index - 1
241 };
242 self.editor
243 .set_theme(&self.available_themes[self.current_theme_index]);
244 cx.notify();
245 }
246
247 fn next_language(&mut self, _: &NextLanguage, _window: &mut Window, cx: &mut Context<Self>) {
248 self.current_language_index =
249 (self.current_language_index + 1) % self.available_languages.len();
250 let (language, _, sample_code) = &self.available_languages[self.current_language_index];
251 self.editor.set_language(language.clone());
252 self.editor
253 .update_buffer(sample_code.lines().map(|s| s.to_string()).collect());
254 cx.notify();
255 }
256
257 fn previous_language(
258 &mut self,
259 _: &PreviousLanguage,
260 _window: &mut Window,
261 cx: &mut Context<Self>,
262 ) {
263 self.current_language_index = if self.current_language_index == 0 {
264 self.available_languages.len() - 1
265 } else {
266 self.current_language_index - 1
267 };
268 let (language, _, sample_code) = &self.available_languages[self.current_language_index];
269 self.editor.set_language(language.clone());
270 self.editor
271 .update_buffer(sample_code.lines().map(|s| s.to_string()).collect());
272 cx.notify();
273 }pub fn current_theme(&self) -> &str
Sourcepub fn set_theme(&mut self, theme: &str)
pub fn set_theme(&mut self, theme: &str)
Examples found in repository?
examples/editor_demo.rs (line 81)
47 fn new(cx: &mut Context<Self>) -> Self {
48 let focus_handle = cx.focus_handle();
49
50 let initial_code = vec![
51 "// Rust sample code".to_string(),
52 "use std::collections::HashMap;".to_string(),
53 "".to_string(),
54 "fn main() {".to_string(),
55 " let mut count = 0;".to_string(),
56 " ".to_string(),
57 " // Count from 1 to 10".to_string(),
58 " for i in 1..=10 {".to_string(),
59 " count += i;".to_string(),
60 " }".to_string(),
61 " ".to_string(),
62 " // HashMap example".to_string(),
63 " let mut scores = HashMap::new();".to_string(),
64 " scores.insert(\"Blue\", 10);".to_string(),
65 " scores.insert(\"Yellow\", 50);".to_string(),
66 " ".to_string(),
67 " println!(\"Final count: {}\", count);".to_string(),
68 "}".to_string(),
69 ];
70
71 let mut editor = Editor::new("editor", initial_code);
72
73 let highlighter = SyntaxHighlighter::new();
74 let available_themes = highlighter.available_themes();
75
76 let default_theme_index = available_themes
77 .iter()
78 .position(|t| t == "base16-ocean.dark")
79 .unwrap_or(0);
80
81 editor.set_theme(&available_themes[default_theme_index]);
82
83 let available_languages = vec![
84 ("Rust".to_string(), "rs".to_string(), get_rust_sample()),
85 (
86 "Plain Text".to_string(),
87 "txt".to_string(),
88 get_plain_text_sample(),
89 ),
90 ];
91
92 editor.set_language("Rust".to_string());
93
94 Self {
95 focus_handle,
96 editor,
97 current_theme_index: default_theme_index,
98 available_themes,
99 current_language_index: 0,
100 available_languages,
101 }
102 }
103
104 fn get_selected_text(&self) -> String {
105 self.editor.get_selected_text()
106 }
107
108 // Action handlers
109 fn move_up(&mut self, _: &MoveUp, _window: &mut Window, cx: &mut Context<Self>) {
110 self.editor.move_up(false);
111 cx.notify();
112 }
113
114 fn move_down(&mut self, _: &MoveDown, _window: &mut Window, cx: &mut Context<Self>) {
115 self.editor.move_down(false);
116 cx.notify();
117 }
118
119 fn move_left(&mut self, _: &MoveLeft, _window: &mut Window, cx: &mut Context<Self>) {
120 self.editor.move_left(false);
121 cx.notify();
122 }
123
124 fn move_right(&mut self, _: &MoveRight, _window: &mut Window, cx: &mut Context<Self>) {
125 self.editor.move_right(false);
126 cx.notify();
127 }
128
129 fn move_up_with_shift(
130 &mut self,
131 _: &MoveUpWithShift,
132 _window: &mut Window,
133 cx: &mut Context<Self>,
134 ) {
135 self.editor.move_up(true);
136 cx.notify();
137 }
138
139 fn move_down_with_shift(
140 &mut self,
141 _: &MoveDownWithShift,
142 _window: &mut Window,
143 cx: &mut Context<Self>,
144 ) {
145 self.editor.move_down(true);
146 cx.notify();
147 }
148
149 fn move_left_with_shift(
150 &mut self,
151 _: &MoveLeftWithShift,
152 _window: &mut Window,
153 cx: &mut Context<Self>,
154 ) {
155 self.editor.move_left(true);
156 cx.notify();
157 }
158
159 fn move_right_with_shift(
160 &mut self,
161 _: &MoveRightWithShift,
162 _window: &mut Window,
163 cx: &mut Context<Self>,
164 ) {
165 self.editor.move_right(true);
166 cx.notify();
167 }
168
169 fn backspace(&mut self, _: &Backspace, _window: &mut Window, cx: &mut Context<Self>) {
170 self.editor.backspace();
171 cx.notify();
172 }
173
174 fn delete(&mut self, _: &Delete, _window: &mut Window, cx: &mut Context<Self>) {
175 self.editor.delete();
176 cx.notify();
177 }
178
179 fn insert_newline(&mut self, _: &InsertNewline, _window: &mut Window, cx: &mut Context<Self>) {
180 self.editor.insert_newline();
181 cx.notify();
182 }
183
184 fn select_all(&mut self, _: &SelectAll, _window: &mut Window, cx: &mut Context<Self>) {
185 self.editor.select_all();
186 cx.notify();
187 }
188
189 fn escape(&mut self, _: &Escape, _window: &mut Window, cx: &mut Context<Self>) {
190 self.editor.clear_selection();
191 cx.notify();
192 }
193
194 fn copy(&mut self, _: &Copy, _window: &mut Window, cx: &mut Context<Self>) {
195 let selected_text = self.get_selected_text();
196 if !selected_text.is_empty() {
197 cx.write_to_clipboard(ClipboardItem::new_string(selected_text));
198 }
199 }
200
201 fn cut(&mut self, _: &Cut, _window: &mut Window, cx: &mut Context<Self>) {
202 let selected_text = self.get_selected_text();
203 if !selected_text.is_empty() {
204 cx.write_to_clipboard(ClipboardItem::new_string(selected_text));
205 self.editor.delete_selection();
206 cx.notify();
207 }
208 }
209
210 fn paste(&mut self, _: &Paste, _window: &mut Window, cx: &mut Context<Self>) {
211 if let Some(clipboard) = cx.read_from_clipboard() {
212 if let Some(text) = clipboard.text() {
213 // Delete selection if exists
214 self.editor.delete_selection();
215
216 // Insert text character by character (simplified)
217 for ch in text.chars() {
218 if ch == '\n' {
219 self.editor.insert_newline();
220 } else if ch != '\r' {
221 self.editor.insert_char(ch);
222 }
223 }
224 cx.notify();
225 }
226 }
227 }
228
229 fn next_theme(&mut self, _: &NextTheme, _window: &mut Window, cx: &mut Context<Self>) {
230 self.current_theme_index = (self.current_theme_index + 1) % self.available_themes.len();
231 self.editor
232 .set_theme(&self.available_themes[self.current_theme_index]);
233 cx.notify();
234 }
235
236 fn previous_theme(&mut self, _: &PreviousTheme, _window: &mut Window, cx: &mut Context<Self>) {
237 self.current_theme_index = if self.current_theme_index == 0 {
238 self.available_themes.len() - 1
239 } else {
240 self.current_theme_index - 1
241 };
242 self.editor
243 .set_theme(&self.available_themes[self.current_theme_index]);
244 cx.notify();
245 }Sourcepub fn update_buffer(&mut self, lines: Vec<String>)
pub fn update_buffer(&mut self, lines: Vec<String>)
Examples found in repository?
examples/editor_demo.rs (line 253)
247 fn next_language(&mut self, _: &NextLanguage, _window: &mut Window, cx: &mut Context<Self>) {
248 self.current_language_index =
249 (self.current_language_index + 1) % self.available_languages.len();
250 let (language, _, sample_code) = &self.available_languages[self.current_language_index];
251 self.editor.set_language(language.clone());
252 self.editor
253 .update_buffer(sample_code.lines().map(|s| s.to_string()).collect());
254 cx.notify();
255 }
256
257 fn previous_language(
258 &mut self,
259 _: &PreviousLanguage,
260 _window: &mut Window,
261 cx: &mut Context<Self>,
262 ) {
263 self.current_language_index = if self.current_language_index == 0 {
264 self.available_languages.len() - 1
265 } else {
266 self.current_language_index - 1
267 };
268 let (language, _, sample_code) = &self.available_languages[self.current_language_index];
269 self.editor.set_language(language.clone());
270 self.editor
271 .update_buffer(sample_code.lines().map(|s| s.to_string()).collect());
272 cx.notify();
273 }Sourcepub fn update_line(&mut self, line_index: usize, new_content: String)
pub fn update_line(&mut self, line_index: usize, new_content: String)
Update buffer content at a specific line (for future incremental updates)
Sourcepub fn highlight_line(
&mut self,
line: &str,
line_index: usize,
font_family: SharedString,
font_size: f32,
) -> Vec<TextRun>
pub fn highlight_line( &mut self, line: &str, line_index: usize, font_family: SharedString, font_size: f32, ) -> Vec<TextRun>
Get syntax highlighting for a line
Sourcepub fn move_left(&mut self, shift_held: bool)
pub fn move_left(&mut self, shift_held: bool)
Examples found in repository?
examples/editor_demo.rs (line 120)
119 fn move_left(&mut self, _: &MoveLeft, _window: &mut Window, cx: &mut Context<Self>) {
120 self.editor.move_left(false);
121 cx.notify();
122 }
123
124 fn move_right(&mut self, _: &MoveRight, _window: &mut Window, cx: &mut Context<Self>) {
125 self.editor.move_right(false);
126 cx.notify();
127 }
128
129 fn move_up_with_shift(
130 &mut self,
131 _: &MoveUpWithShift,
132 _window: &mut Window,
133 cx: &mut Context<Self>,
134 ) {
135 self.editor.move_up(true);
136 cx.notify();
137 }
138
139 fn move_down_with_shift(
140 &mut self,
141 _: &MoveDownWithShift,
142 _window: &mut Window,
143 cx: &mut Context<Self>,
144 ) {
145 self.editor.move_down(true);
146 cx.notify();
147 }
148
149 fn move_left_with_shift(
150 &mut self,
151 _: &MoveLeftWithShift,
152 _window: &mut Window,
153 cx: &mut Context<Self>,
154 ) {
155 self.editor.move_left(true);
156 cx.notify();
157 }Sourcepub fn move_right(&mut self, shift_held: bool)
pub fn move_right(&mut self, shift_held: bool)
Examples found in repository?
examples/editor_demo.rs (line 125)
124 fn move_right(&mut self, _: &MoveRight, _window: &mut Window, cx: &mut Context<Self>) {
125 self.editor.move_right(false);
126 cx.notify();
127 }
128
129 fn move_up_with_shift(
130 &mut self,
131 _: &MoveUpWithShift,
132 _window: &mut Window,
133 cx: &mut Context<Self>,
134 ) {
135 self.editor.move_up(true);
136 cx.notify();
137 }
138
139 fn move_down_with_shift(
140 &mut self,
141 _: &MoveDownWithShift,
142 _window: &mut Window,
143 cx: &mut Context<Self>,
144 ) {
145 self.editor.move_down(true);
146 cx.notify();
147 }
148
149 fn move_left_with_shift(
150 &mut self,
151 _: &MoveLeftWithShift,
152 _window: &mut Window,
153 cx: &mut Context<Self>,
154 ) {
155 self.editor.move_left(true);
156 cx.notify();
157 }
158
159 fn move_right_with_shift(
160 &mut self,
161 _: &MoveRightWithShift,
162 _window: &mut Window,
163 cx: &mut Context<Self>,
164 ) {
165 self.editor.move_right(true);
166 cx.notify();
167 }Sourcepub fn move_up(&mut self, shift_held: bool)
pub fn move_up(&mut self, shift_held: bool)
Examples found in repository?
examples/editor_demo.rs (line 110)
109 fn move_up(&mut self, _: &MoveUp, _window: &mut Window, cx: &mut Context<Self>) {
110 self.editor.move_up(false);
111 cx.notify();
112 }
113
114 fn move_down(&mut self, _: &MoveDown, _window: &mut Window, cx: &mut Context<Self>) {
115 self.editor.move_down(false);
116 cx.notify();
117 }
118
119 fn move_left(&mut self, _: &MoveLeft, _window: &mut Window, cx: &mut Context<Self>) {
120 self.editor.move_left(false);
121 cx.notify();
122 }
123
124 fn move_right(&mut self, _: &MoveRight, _window: &mut Window, cx: &mut Context<Self>) {
125 self.editor.move_right(false);
126 cx.notify();
127 }
128
129 fn move_up_with_shift(
130 &mut self,
131 _: &MoveUpWithShift,
132 _window: &mut Window,
133 cx: &mut Context<Self>,
134 ) {
135 self.editor.move_up(true);
136 cx.notify();
137 }Sourcepub fn move_down(&mut self, shift_held: bool)
pub fn move_down(&mut self, shift_held: bool)
Examples found in repository?
examples/editor_demo.rs (line 115)
114 fn move_down(&mut self, _: &MoveDown, _window: &mut Window, cx: &mut Context<Self>) {
115 self.editor.move_down(false);
116 cx.notify();
117 }
118
119 fn move_left(&mut self, _: &MoveLeft, _window: &mut Window, cx: &mut Context<Self>) {
120 self.editor.move_left(false);
121 cx.notify();
122 }
123
124 fn move_right(&mut self, _: &MoveRight, _window: &mut Window, cx: &mut Context<Self>) {
125 self.editor.move_right(false);
126 cx.notify();
127 }
128
129 fn move_up_with_shift(
130 &mut self,
131 _: &MoveUpWithShift,
132 _window: &mut Window,
133 cx: &mut Context<Self>,
134 ) {
135 self.editor.move_up(true);
136 cx.notify();
137 }
138
139 fn move_down_with_shift(
140 &mut self,
141 _: &MoveDownWithShift,
142 _window: &mut Window,
143 cx: &mut Context<Self>,
144 ) {
145 self.editor.move_down(true);
146 cx.notify();
147 }Sourcepub fn select_all(&mut self)
pub fn select_all(&mut self)
Sourcepub fn has_selection(&self) -> bool
pub fn has_selection(&self) -> bool
Examples found in repository?
examples/editor_demo.rs (line 289)
277 fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
278 let _current_theme = &self.available_themes[self.current_theme_index];
279 let (current_language, _, _) = &self.available_languages[self.current_language_index];
280
281 let language = match current_language.as_str() {
282 "Rust" => Language::Rust,
283 _ => Language::PlainText,
284 };
285
286 let cursor_position = self.editor.cursor_position();
287 let cursor_point = Point::new(cursor_position.col, cursor_position.row);
288
289 let selection = if self.editor.has_selection() {
290 let selected_text = self.get_selected_text();
291 Some(Selection {
292 lines: selected_text.matches('\n').count(),
293 chars: selected_text.len(),
294 })
295 } else {
296 None
297 };
298
299 div()
300 .key_context("editor")
301 .size_full()
302 .flex()
303 .flex_col()
304 .child(
305 div()
306 .flex_grow()
307 .track_focus(&self.focus_handle)
308 .on_action(cx.listener(Self::move_up))
309 .on_action(cx.listener(Self::move_down))
310 .on_action(cx.listener(Self::move_left))
311 .on_action(cx.listener(Self::move_right))
312 .on_action(cx.listener(Self::move_up_with_shift))
313 .on_action(cx.listener(Self::move_down_with_shift))
314 .on_action(cx.listener(Self::move_left_with_shift))
315 .on_action(cx.listener(Self::move_right_with_shift))
316 .on_action(cx.listener(Self::backspace))
317 .on_action(cx.listener(Self::delete))
318 .on_action(cx.listener(Self::insert_newline))
319 .on_action(cx.listener(Self::select_all))
320 .on_action(cx.listener(Self::escape))
321 .on_action(cx.listener(Self::copy))
322 .on_action(cx.listener(Self::cut))
323 .on_action(cx.listener(Self::paste))
324 .on_action(cx.listener(Self::next_theme))
325 .on_action(cx.listener(Self::previous_theme))
326 .on_action(cx.listener(Self::next_language))
327 .on_action(cx.listener(Self::previous_language))
328 .on_key_down(cx.listener(
329 |this: &mut Self, event: &KeyDownEvent, _window, cx| {
330 // Handle character input
331 if let Some(text) = &event.keystroke.key_char {
332 if !event.keystroke.modifiers.platform
333 && !event.keystroke.modifiers.control
334 && !event.keystroke.modifiers.function
335 {
336 for ch in text.chars() {
337 this.editor.insert_char(ch);
338 }
339 cx.notify();
340 }
341 }
342 },
343 ))
344 .child(EditorElement::new(self.editor.clone())),
345 )
346 .child(MetaLine::new(cursor_point, language, selection))
347 }pub fn get_selection_range(&self) -> Option<(CursorPosition, CursorPosition)>
Sourcepub fn delete_selection(&mut self) -> bool
pub fn delete_selection(&mut self) -> bool
Examples found in repository?
examples/editor_demo.rs (line 205)
201 fn cut(&mut self, _: &Cut, _window: &mut Window, cx: &mut Context<Self>) {
202 let selected_text = self.get_selected_text();
203 if !selected_text.is_empty() {
204 cx.write_to_clipboard(ClipboardItem::new_string(selected_text));
205 self.editor.delete_selection();
206 cx.notify();
207 }
208 }
209
210 fn paste(&mut self, _: &Paste, _window: &mut Window, cx: &mut Context<Self>) {
211 if let Some(clipboard) = cx.read_from_clipboard() {
212 if let Some(text) = clipboard.text() {
213 // Delete selection if exists
214 self.editor.delete_selection();
215
216 // Insert text character by character (simplified)
217 for ch in text.chars() {
218 if ch == '\n' {
219 self.editor.insert_newline();
220 } else if ch != '\r' {
221 self.editor.insert_char(ch);
222 }
223 }
224 cx.notify();
225 }
226 }
227 }Sourcepub fn get_selected_text(&self) -> String
pub fn get_selected_text(&self) -> String
Sourcepub fn insert_char(&mut self, ch: char)
pub fn insert_char(&mut self, ch: char)
Examples found in repository?
examples/editor_demo.rs (line 221)
210 fn paste(&mut self, _: &Paste, _window: &mut Window, cx: &mut Context<Self>) {
211 if let Some(clipboard) = cx.read_from_clipboard() {
212 if let Some(text) = clipboard.text() {
213 // Delete selection if exists
214 self.editor.delete_selection();
215
216 // Insert text character by character (simplified)
217 for ch in text.chars() {
218 if ch == '\n' {
219 self.editor.insert_newline();
220 } else if ch != '\r' {
221 self.editor.insert_char(ch);
222 }
223 }
224 cx.notify();
225 }
226 }
227 }
228
229 fn next_theme(&mut self, _: &NextTheme, _window: &mut Window, cx: &mut Context<Self>) {
230 self.current_theme_index = (self.current_theme_index + 1) % self.available_themes.len();
231 self.editor
232 .set_theme(&self.available_themes[self.current_theme_index]);
233 cx.notify();
234 }
235
236 fn previous_theme(&mut self, _: &PreviousTheme, _window: &mut Window, cx: &mut Context<Self>) {
237 self.current_theme_index = if self.current_theme_index == 0 {
238 self.available_themes.len() - 1
239 } else {
240 self.current_theme_index - 1
241 };
242 self.editor
243 .set_theme(&self.available_themes[self.current_theme_index]);
244 cx.notify();
245 }
246
247 fn next_language(&mut self, _: &NextLanguage, _window: &mut Window, cx: &mut Context<Self>) {
248 self.current_language_index =
249 (self.current_language_index + 1) % self.available_languages.len();
250 let (language, _, sample_code) = &self.available_languages[self.current_language_index];
251 self.editor.set_language(language.clone());
252 self.editor
253 .update_buffer(sample_code.lines().map(|s| s.to_string()).collect());
254 cx.notify();
255 }
256
257 fn previous_language(
258 &mut self,
259 _: &PreviousLanguage,
260 _window: &mut Window,
261 cx: &mut Context<Self>,
262 ) {
263 self.current_language_index = if self.current_language_index == 0 {
264 self.available_languages.len() - 1
265 } else {
266 self.current_language_index - 1
267 };
268 let (language, _, sample_code) = &self.available_languages[self.current_language_index];
269 self.editor.set_language(language.clone());
270 self.editor
271 .update_buffer(sample_code.lines().map(|s| s.to_string()).collect());
272 cx.notify();
273 }
274}
275
276impl Render for EditorView {
277 fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
278 let _current_theme = &self.available_themes[self.current_theme_index];
279 let (current_language, _, _) = &self.available_languages[self.current_language_index];
280
281 let language = match current_language.as_str() {
282 "Rust" => Language::Rust,
283 _ => Language::PlainText,
284 };
285
286 let cursor_position = self.editor.cursor_position();
287 let cursor_point = Point::new(cursor_position.col, cursor_position.row);
288
289 let selection = if self.editor.has_selection() {
290 let selected_text = self.get_selected_text();
291 Some(Selection {
292 lines: selected_text.matches('\n').count(),
293 chars: selected_text.len(),
294 })
295 } else {
296 None
297 };
298
299 div()
300 .key_context("editor")
301 .size_full()
302 .flex()
303 .flex_col()
304 .child(
305 div()
306 .flex_grow()
307 .track_focus(&self.focus_handle)
308 .on_action(cx.listener(Self::move_up))
309 .on_action(cx.listener(Self::move_down))
310 .on_action(cx.listener(Self::move_left))
311 .on_action(cx.listener(Self::move_right))
312 .on_action(cx.listener(Self::move_up_with_shift))
313 .on_action(cx.listener(Self::move_down_with_shift))
314 .on_action(cx.listener(Self::move_left_with_shift))
315 .on_action(cx.listener(Self::move_right_with_shift))
316 .on_action(cx.listener(Self::backspace))
317 .on_action(cx.listener(Self::delete))
318 .on_action(cx.listener(Self::insert_newline))
319 .on_action(cx.listener(Self::select_all))
320 .on_action(cx.listener(Self::escape))
321 .on_action(cx.listener(Self::copy))
322 .on_action(cx.listener(Self::cut))
323 .on_action(cx.listener(Self::paste))
324 .on_action(cx.listener(Self::next_theme))
325 .on_action(cx.listener(Self::previous_theme))
326 .on_action(cx.listener(Self::next_language))
327 .on_action(cx.listener(Self::previous_language))
328 .on_key_down(cx.listener(
329 |this: &mut Self, event: &KeyDownEvent, _window, cx| {
330 // Handle character input
331 if let Some(text) = &event.keystroke.key_char {
332 if !event.keystroke.modifiers.platform
333 && !event.keystroke.modifiers.control
334 && !event.keystroke.modifiers.function
335 {
336 for ch in text.chars() {
337 this.editor.insert_char(ch);
338 }
339 cx.notify();
340 }
341 }
342 },
343 ))
344 .child(EditorElement::new(self.editor.clone())),
345 )
346 .child(MetaLine::new(cursor_point, language, selection))
347 }Sourcepub fn insert_newline(&mut self)
pub fn insert_newline(&mut self)
Examples found in repository?
examples/editor_demo.rs (line 180)
179 fn insert_newline(&mut self, _: &InsertNewline, _window: &mut Window, cx: &mut Context<Self>) {
180 self.editor.insert_newline();
181 cx.notify();
182 }
183
184 fn select_all(&mut self, _: &SelectAll, _window: &mut Window, cx: &mut Context<Self>) {
185 self.editor.select_all();
186 cx.notify();
187 }
188
189 fn escape(&mut self, _: &Escape, _window: &mut Window, cx: &mut Context<Self>) {
190 self.editor.clear_selection();
191 cx.notify();
192 }
193
194 fn copy(&mut self, _: &Copy, _window: &mut Window, cx: &mut Context<Self>) {
195 let selected_text = self.get_selected_text();
196 if !selected_text.is_empty() {
197 cx.write_to_clipboard(ClipboardItem::new_string(selected_text));
198 }
199 }
200
201 fn cut(&mut self, _: &Cut, _window: &mut Window, cx: &mut Context<Self>) {
202 let selected_text = self.get_selected_text();
203 if !selected_text.is_empty() {
204 cx.write_to_clipboard(ClipboardItem::new_string(selected_text));
205 self.editor.delete_selection();
206 cx.notify();
207 }
208 }
209
210 fn paste(&mut self, _: &Paste, _window: &mut Window, cx: &mut Context<Self>) {
211 if let Some(clipboard) = cx.read_from_clipboard() {
212 if let Some(text) = clipboard.text() {
213 // Delete selection if exists
214 self.editor.delete_selection();
215
216 // Insert text character by character (simplified)
217 for ch in text.chars() {
218 if ch == '\n' {
219 self.editor.insert_newline();
220 } else if ch != '\r' {
221 self.editor.insert_char(ch);
222 }
223 }
224 cx.notify();
225 }
226 }
227 }Trait Implementations§
Auto Trait Implementations§
impl Freeze for Editor
impl !RefUnwindSafe for Editor
impl !Send for Editor
impl !Sync for Editor
impl Unpin for Editor
impl !UnwindSafe for Editor
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Convert
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Convert
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
Convert
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
Convert
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more