1use crate::input::keybindings::{Action, KeyContext};
4use crate::types::context_keys;
5use rust_i18n::t;
6
7#[derive(Debug, Clone, PartialEq)]
9pub enum CommandSource {
10 Builtin,
12 Plugin(String),
14}
15
16#[derive(Debug, Clone)]
18pub struct Command {
19 pub name: String,
21 pub description: String,
23 pub action: Action,
25 pub contexts: Vec<KeyContext>,
27 pub custom_contexts: Vec<String>,
30 pub source: CommandSource,
32}
33
34impl Command {
35 pub fn get_localized_name(&self) -> String {
37 if self.name.starts_with('%') {
38 if let CommandSource::Plugin(ref plugin_name) = self.source {
39 return crate::i18n::translate_plugin_string(
40 plugin_name,
41 &self.name[1..],
42 &std::collections::HashMap::new(),
43 );
44 }
45 }
46 self.name.clone()
47 }
48
49 pub fn get_localized_description(&self) -> String {
51 if self.description.starts_with('%') {
52 if let CommandSource::Plugin(ref plugin_name) = self.source {
53 return crate::i18n::translate_plugin_string(
54 plugin_name,
55 &self.description[1..],
56 &std::collections::HashMap::new(),
57 );
58 }
59 }
60 self.description.clone()
61 }
62}
63
64#[derive(Debug, Clone, PartialEq)]
66pub struct Suggestion {
67 pub text: String,
69 pub description: Option<String>,
71 pub value: Option<String>,
73 pub disabled: bool,
75 pub keybinding: Option<String>,
77 pub source: Option<CommandSource>,
79}
80
81impl Suggestion {
82 pub fn new(text: String) -> Self {
83 Self {
84 text,
85 description: None,
86 value: None,
87 disabled: false,
88 keybinding: None,
89 source: None,
90 }
91 }
92
93 pub fn with_description(text: String, description: String) -> Self {
94 Self {
95 text,
96 description: Some(description),
97 value: None,
98 disabled: false,
99 keybinding: None,
100 source: None,
101 }
102 }
103
104 pub fn with_description_and_disabled(
105 text: String,
106 description: String,
107 disabled: bool,
108 ) -> Self {
109 Self {
110 text,
111 description: Some(description),
112 value: None,
113 disabled,
114 keybinding: None,
115 source: None,
116 }
117 }
118
119 pub fn with_all(
120 text: String,
121 description: Option<String>,
122 disabled: bool,
123 keybinding: Option<String>,
124 ) -> Self {
125 Self {
126 text,
127 description,
128 value: None,
129 disabled,
130 keybinding,
131 source: None,
132 }
133 }
134
135 pub fn with_source(
136 text: String,
137 description: Option<String>,
138 disabled: bool,
139 keybinding: Option<String>,
140 source: Option<CommandSource>,
141 ) -> Self {
142 Self {
143 text,
144 description,
145 value: None,
146 disabled,
147 keybinding,
148 source,
149 }
150 }
151
152 pub fn get_value(&self) -> &str {
153 self.value.as_ref().unwrap_or(&self.text)
154 }
155}
156
157struct CommandDef {
159 name_key: &'static str,
160 desc_key: &'static str,
161 action: fn() -> Action,
162 contexts: &'static [KeyContext],
163 custom_contexts: &'static [&'static str],
164}
165
166use KeyContext::{FileExplorer, Normal, Terminal};
167
168static COMMAND_DEFS: &[CommandDef] = &[
171 CommandDef {
173 name_key: "cmd.open_file",
174 desc_key: "cmd.open_file_desc",
175 action: || Action::Open,
176 contexts: &[],
177 custom_contexts: &[],
178 },
179 CommandDef {
180 name_key: "cmd.switch_project",
181 desc_key: "cmd.switch_project_desc",
182 action: || Action::SwitchProject,
183 contexts: &[],
184 custom_contexts: &[],
185 },
186 CommandDef {
187 name_key: "cmd.save_file",
188 desc_key: "cmd.save_file_desc",
189 action: || Action::Save,
190 contexts: &[Normal],
191 custom_contexts: &[],
192 },
193 CommandDef {
194 name_key: "cmd.save_file_as",
195 desc_key: "cmd.save_file_as_desc",
196 action: || Action::SaveAs,
197 contexts: &[Normal],
198 custom_contexts: &[],
199 },
200 CommandDef {
201 name_key: "cmd.new_file",
202 desc_key: "cmd.new_file_desc",
203 action: || Action::New,
204 contexts: &[],
205 custom_contexts: &[],
206 },
207 CommandDef {
208 name_key: "cmd.close_buffer",
209 desc_key: "cmd.close_buffer_desc",
210 action: || Action::Close,
211 contexts: &[Normal, Terminal],
212 custom_contexts: &[],
213 },
214 CommandDef {
215 name_key: "cmd.close_tab",
216 desc_key: "cmd.close_tab_desc",
217 action: || Action::CloseTab,
218 contexts: &[Normal, Terminal],
219 custom_contexts: &[],
220 },
221 CommandDef {
222 name_key: "cmd.revert_file",
223 desc_key: "cmd.revert_file_desc",
224 action: || Action::Revert,
225 contexts: &[Normal],
226 custom_contexts: &[],
227 },
228 CommandDef {
229 name_key: "cmd.toggle_auto_revert",
230 desc_key: "cmd.toggle_auto_revert_desc",
231 action: || Action::ToggleAutoRevert,
232 contexts: &[],
233 custom_contexts: &[],
234 },
235 CommandDef {
236 name_key: "cmd.format_buffer",
237 desc_key: "cmd.format_buffer_desc",
238 action: || Action::FormatBuffer,
239 contexts: &[Normal],
240 custom_contexts: &[],
241 },
242 CommandDef {
243 name_key: "cmd.trim_trailing_whitespace",
244 desc_key: "cmd.trim_trailing_whitespace_desc",
245 action: || Action::TrimTrailingWhitespace,
246 contexts: &[Normal],
247 custom_contexts: &[],
248 },
249 CommandDef {
250 name_key: "cmd.ensure_final_newline",
251 desc_key: "cmd.ensure_final_newline_desc",
252 action: || Action::EnsureFinalNewline,
253 contexts: &[Normal],
254 custom_contexts: &[],
255 },
256 CommandDef {
257 name_key: "cmd.quit",
258 desc_key: "cmd.quit_desc",
259 action: || Action::Quit,
260 contexts: &[],
261 custom_contexts: &[],
262 },
263 CommandDef {
264 name_key: "cmd.detach",
265 desc_key: "cmd.detach_desc",
266 action: || Action::Detach,
267 contexts: &[],
268 custom_contexts: &[context_keys::SESSION_MODE],
269 },
270 CommandDef {
272 name_key: "cmd.undo",
273 desc_key: "cmd.undo_desc",
274 action: || Action::Undo,
275 contexts: &[Normal],
276 custom_contexts: &[],
277 },
278 CommandDef {
279 name_key: "cmd.redo",
280 desc_key: "cmd.redo_desc",
281 action: || Action::Redo,
282 contexts: &[Normal],
283 custom_contexts: &[],
284 },
285 CommandDef {
286 name_key: "cmd.copy",
287 desc_key: "cmd.copy_desc",
288 action: || Action::Copy,
289 contexts: &[Normal],
290 custom_contexts: &[],
291 },
292 CommandDef {
293 name_key: "cmd.copy_with_formatting",
294 desc_key: "cmd.copy_with_formatting_desc",
295 action: || Action::CopyWithTheme(String::new()),
296 contexts: &[Normal],
297 custom_contexts: &[],
298 },
299 CommandDef {
300 name_key: "cmd.cut",
301 desc_key: "cmd.cut_desc",
302 action: || Action::Cut,
303 contexts: &[Normal],
304 custom_contexts: &[],
305 },
306 CommandDef {
307 name_key: "cmd.paste",
308 desc_key: "cmd.paste_desc",
309 action: || Action::Paste,
310 contexts: &[Normal],
311 custom_contexts: &[],
312 },
313 CommandDef {
314 name_key: "cmd.delete_line",
315 desc_key: "cmd.delete_line_desc",
316 action: || Action::DeleteLine,
317 contexts: &[Normal],
318 custom_contexts: &[],
319 },
320 CommandDef {
321 name_key: "cmd.delete_word_backward",
322 desc_key: "cmd.delete_word_backward_desc",
323 action: || Action::DeleteWordBackward,
324 contexts: &[Normal],
325 custom_contexts: &[],
326 },
327 CommandDef {
328 name_key: "cmd.delete_word_forward",
329 desc_key: "cmd.delete_word_forward_desc",
330 action: || Action::DeleteWordForward,
331 contexts: &[Normal],
332 custom_contexts: &[],
333 },
334 CommandDef {
335 name_key: "cmd.delete_to_end_of_line",
336 desc_key: "cmd.delete_to_end_of_line_desc",
337 action: || Action::DeleteToLineEnd,
338 contexts: &[Normal],
339 custom_contexts: &[],
340 },
341 CommandDef {
342 name_key: "cmd.transpose_characters",
343 desc_key: "cmd.transpose_characters_desc",
344 action: || Action::TransposeChars,
345 contexts: &[Normal],
346 custom_contexts: &[],
347 },
348 CommandDef {
349 name_key: "cmd.transform_uppercase",
350 desc_key: "cmd.transform_uppercase_desc",
351 action: || Action::ToUpperCase,
352 contexts: &[Normal],
353 custom_contexts: &[],
354 },
355 CommandDef {
356 name_key: "cmd.transform_lowercase",
357 desc_key: "cmd.transform_lowercase_desc",
358 action: || Action::ToLowerCase,
359 contexts: &[Normal],
360 custom_contexts: &[],
361 },
362 CommandDef {
363 name_key: "cmd.sort_lines",
364 desc_key: "cmd.sort_lines_desc",
365 action: || Action::SortLines,
366 contexts: &[Normal],
367 custom_contexts: &[],
368 },
369 CommandDef {
370 name_key: "cmd.open_line",
371 desc_key: "cmd.open_line_desc",
372 action: || Action::OpenLine,
373 contexts: &[Normal],
374 custom_contexts: &[],
375 },
376 CommandDef {
377 name_key: "cmd.duplicate_line",
378 desc_key: "cmd.duplicate_line_desc",
379 action: || Action::DuplicateLine,
380 contexts: &[Normal],
381 custom_contexts: &[],
382 },
383 CommandDef {
384 name_key: "cmd.recenter",
385 desc_key: "cmd.recenter_desc",
386 action: || Action::Recenter,
387 contexts: &[Normal],
388 custom_contexts: &[],
389 },
390 CommandDef {
391 name_key: "cmd.set_mark",
392 desc_key: "cmd.set_mark_desc",
393 action: || Action::SetMark,
394 contexts: &[Normal],
395 custom_contexts: &[],
396 },
397 CommandDef {
399 name_key: "cmd.select_all",
400 desc_key: "cmd.select_all_desc",
401 action: || Action::SelectAll,
402 contexts: &[Normal],
403 custom_contexts: &[],
404 },
405 CommandDef {
406 name_key: "cmd.select_word",
407 desc_key: "cmd.select_word_desc",
408 action: || Action::SelectWord,
409 contexts: &[Normal],
410 custom_contexts: &[],
411 },
412 CommandDef {
413 name_key: "cmd.select_line",
414 desc_key: "cmd.select_line_desc",
415 action: || Action::SelectLine,
416 contexts: &[Normal],
417 custom_contexts: &[],
418 },
419 CommandDef {
420 name_key: "cmd.expand_selection",
421 desc_key: "cmd.expand_selection_desc",
422 action: || Action::ExpandSelection,
423 contexts: &[Normal],
424 custom_contexts: &[],
425 },
426 CommandDef {
428 name_key: "cmd.add_cursor_above",
429 desc_key: "cmd.add_cursor_above_desc",
430 action: || Action::AddCursorAbove,
431 contexts: &[Normal],
432 custom_contexts: &[],
433 },
434 CommandDef {
435 name_key: "cmd.add_cursor_below",
436 desc_key: "cmd.add_cursor_below_desc",
437 action: || Action::AddCursorBelow,
438 contexts: &[Normal],
439 custom_contexts: &[],
440 },
441 CommandDef {
442 name_key: "cmd.add_cursor_next_match",
443 desc_key: "cmd.add_cursor_next_match_desc",
444 action: || Action::AddCursorNextMatch,
445 contexts: &[Normal],
446 custom_contexts: &[],
447 },
448 CommandDef {
449 name_key: "cmd.remove_secondary_cursors",
450 desc_key: "cmd.remove_secondary_cursors_desc",
451 action: || Action::RemoveSecondaryCursors,
452 contexts: &[Normal],
453 custom_contexts: &[],
454 },
455 CommandDef {
457 name_key: "cmd.next_buffer",
458 desc_key: "cmd.next_buffer_desc",
459 action: || Action::NextBuffer,
460 contexts: &[Normal, Terminal],
461 custom_contexts: &[],
462 },
463 CommandDef {
464 name_key: "cmd.previous_buffer",
465 desc_key: "cmd.previous_buffer_desc",
466 action: || Action::PrevBuffer,
467 contexts: &[Normal, Terminal],
468 custom_contexts: &[],
469 },
470 CommandDef {
471 name_key: "cmd.switch_to_previous_tab",
472 desc_key: "cmd.switch_to_previous_tab_desc",
473 action: || Action::SwitchToPreviousTab,
474 contexts: &[Normal, Terminal],
475 custom_contexts: &[],
476 },
477 CommandDef {
478 name_key: "cmd.switch_to_tab_by_name",
479 desc_key: "cmd.switch_to_tab_by_name_desc",
480 action: || Action::SwitchToTabByName,
481 contexts: &[Normal, Terminal],
482 custom_contexts: &[],
483 },
484 CommandDef {
486 name_key: "cmd.split_horizontal",
487 desc_key: "cmd.split_horizontal_desc",
488 action: || Action::SplitHorizontal,
489 contexts: &[Normal, Terminal],
490 custom_contexts: &[],
491 },
492 CommandDef {
493 name_key: "cmd.split_vertical",
494 desc_key: "cmd.split_vertical_desc",
495 action: || Action::SplitVertical,
496 contexts: &[Normal, Terminal],
497 custom_contexts: &[],
498 },
499 CommandDef {
500 name_key: "cmd.close_split",
501 desc_key: "cmd.close_split_desc",
502 action: || Action::CloseSplit,
503 contexts: &[Normal, Terminal],
504 custom_contexts: &[],
505 },
506 CommandDef {
507 name_key: "cmd.next_split",
508 desc_key: "cmd.next_split_desc",
509 action: || Action::NextSplit,
510 contexts: &[Normal, Terminal],
511 custom_contexts: &[],
512 },
513 CommandDef {
514 name_key: "cmd.previous_split",
515 desc_key: "cmd.previous_split_desc",
516 action: || Action::PrevSplit,
517 contexts: &[Normal, Terminal],
518 custom_contexts: &[],
519 },
520 CommandDef {
521 name_key: "cmd.increase_split_size",
522 desc_key: "cmd.increase_split_size_desc",
523 action: || Action::IncreaseSplitSize,
524 contexts: &[Normal, Terminal],
525 custom_contexts: &[],
526 },
527 CommandDef {
528 name_key: "cmd.decrease_split_size",
529 desc_key: "cmd.decrease_split_size_desc",
530 action: || Action::DecreaseSplitSize,
531 contexts: &[Normal, Terminal],
532 custom_contexts: &[],
533 },
534 CommandDef {
535 name_key: "cmd.toggle_maximize_split",
536 desc_key: "cmd.toggle_maximize_split_desc",
537 action: || Action::ToggleMaximizeSplit,
538 contexts: &[Normal, Terminal],
539 custom_contexts: &[],
540 },
541 CommandDef {
543 name_key: "cmd.toggle_line_numbers",
544 desc_key: "cmd.toggle_line_numbers_desc",
545 action: || Action::ToggleLineNumbers,
546 contexts: &[Normal],
547 custom_contexts: &[],
548 },
549 CommandDef {
550 name_key: "cmd.toggle_scroll_sync",
551 desc_key: "cmd.toggle_scroll_sync_desc",
552 action: || Action::ToggleScrollSync,
553 contexts: &[Normal],
554 custom_contexts: &[],
555 },
556 CommandDef {
557 name_key: "cmd.toggle_fold",
558 desc_key: "cmd.toggle_fold_desc",
559 action: || Action::ToggleFold,
560 contexts: &[Normal],
561 custom_contexts: &[],
562 },
563 CommandDef {
564 name_key: "cmd.debug_toggle_highlight",
565 desc_key: "cmd.debug_toggle_highlight_desc",
566 action: || Action::ToggleDebugHighlights,
567 contexts: &[Normal],
568 custom_contexts: &[],
569 },
570 CommandDef {
572 name_key: "cmd.add_ruler",
573 desc_key: "cmd.add_ruler_desc",
574 action: || Action::AddRuler,
575 contexts: &[Normal],
576 custom_contexts: &[],
577 },
578 CommandDef {
579 name_key: "cmd.remove_ruler",
580 desc_key: "cmd.remove_ruler_desc",
581 action: || Action::RemoveRuler,
582 contexts: &[Normal],
583 custom_contexts: &[],
584 },
585 CommandDef {
587 name_key: "cmd.set_tab_size",
588 desc_key: "cmd.set_tab_size_desc",
589 action: || Action::SetTabSize,
590 contexts: &[Normal],
591 custom_contexts: &[],
592 },
593 CommandDef {
594 name_key: "cmd.set_line_ending",
595 desc_key: "cmd.set_line_ending_desc",
596 action: || Action::SetLineEnding,
597 contexts: &[Normal],
598 custom_contexts: &[],
599 },
600 CommandDef {
601 name_key: "cmd.set_encoding",
602 desc_key: "cmd.set_encoding_desc",
603 action: || Action::SetEncoding,
604 contexts: &[Normal],
605 custom_contexts: &[],
606 },
607 CommandDef {
608 name_key: "cmd.reload_with_encoding",
609 desc_key: "cmd.reload_with_encoding_desc",
610 action: || Action::ReloadWithEncoding,
611 contexts: &[Normal],
612 custom_contexts: &[],
613 },
614 CommandDef {
615 name_key: "cmd.set_language",
616 desc_key: "cmd.set_language_desc",
617 action: || Action::SetLanguage,
618 contexts: &[Normal],
619 custom_contexts: &[],
620 },
621 CommandDef {
622 name_key: "cmd.toggle_indentation",
623 desc_key: "cmd.toggle_indentation_desc",
624 action: || Action::ToggleIndentationStyle,
625 contexts: &[Normal],
626 custom_contexts: &[],
627 },
628 CommandDef {
629 name_key: "cmd.toggle_tab_indicators",
630 desc_key: "cmd.toggle_tab_indicators_desc",
631 action: || Action::ToggleTabIndicators,
632 contexts: &[Normal],
633 custom_contexts: &[],
634 },
635 CommandDef {
636 name_key: "cmd.toggle_whitespace_indicators",
637 desc_key: "cmd.toggle_whitespace_indicators_desc",
638 action: || Action::ToggleWhitespaceIndicators,
639 contexts: &[Normal],
640 custom_contexts: &[],
641 },
642 CommandDef {
643 name_key: "cmd.reset_buffer_settings",
644 desc_key: "cmd.reset_buffer_settings_desc",
645 action: || Action::ResetBufferSettings,
646 contexts: &[Normal],
647 custom_contexts: &[],
648 },
649 CommandDef {
650 name_key: "cmd.scroll_up",
651 desc_key: "cmd.scroll_up_desc",
652 action: || Action::ScrollUp,
653 contexts: &[Normal],
654 custom_contexts: &[],
655 },
656 CommandDef {
657 name_key: "cmd.scroll_down",
658 desc_key: "cmd.scroll_down_desc",
659 action: || Action::ScrollDown,
660 contexts: &[Normal],
661 custom_contexts: &[],
662 },
663 CommandDef {
664 name_key: "cmd.scroll_tabs_left",
665 desc_key: "cmd.scroll_tabs_left_desc",
666 action: || Action::ScrollTabsLeft,
667 contexts: &[Normal, Terminal],
668 custom_contexts: &[],
669 },
670 CommandDef {
671 name_key: "cmd.scroll_tabs_right",
672 desc_key: "cmd.scroll_tabs_right_desc",
673 action: || Action::ScrollTabsRight,
674 contexts: &[Normal, Terminal],
675 custom_contexts: &[],
676 },
677 CommandDef {
678 name_key: "cmd.toggle_mouse_support",
679 desc_key: "cmd.toggle_mouse_support_desc",
680 action: || Action::ToggleMouseCapture,
681 contexts: &[Normal, Terminal],
682 custom_contexts: &[],
683 },
684 CommandDef {
686 name_key: "cmd.toggle_file_explorer",
687 desc_key: "cmd.toggle_file_explorer_desc",
688 action: || Action::ToggleFileExplorer,
689 contexts: &[Normal, FileExplorer, Terminal],
690 custom_contexts: &[],
691 },
692 CommandDef {
693 name_key: "cmd.toggle_menu_bar",
694 desc_key: "cmd.toggle_menu_bar_desc",
695 action: || Action::ToggleMenuBar,
696 contexts: &[Normal, FileExplorer, Terminal],
697 custom_contexts: &[],
698 },
699 CommandDef {
700 name_key: "cmd.toggle_tab_bar",
701 desc_key: "cmd.toggle_tab_bar_desc",
702 action: || Action::ToggleTabBar,
703 contexts: &[Normal, FileExplorer, Terminal],
704 custom_contexts: &[],
705 },
706 CommandDef {
707 name_key: "cmd.toggle_status_bar",
708 desc_key: "cmd.toggle_status_bar_desc",
709 action: || Action::ToggleStatusBar,
710 contexts: &[Normal, FileExplorer, Terminal],
711 custom_contexts: &[],
712 },
713 CommandDef {
714 name_key: "cmd.toggle_vertical_scrollbar",
715 desc_key: "cmd.toggle_vertical_scrollbar_desc",
716 action: || Action::ToggleVerticalScrollbar,
717 contexts: &[Normal, FileExplorer, Terminal],
718 custom_contexts: &[],
719 },
720 CommandDef {
721 name_key: "cmd.toggle_horizontal_scrollbar",
722 desc_key: "cmd.toggle_horizontal_scrollbar_desc",
723 action: || Action::ToggleHorizontalScrollbar,
724 contexts: &[Normal, FileExplorer, Terminal],
725 custom_contexts: &[],
726 },
727 CommandDef {
728 name_key: "cmd.focus_file_explorer",
729 desc_key: "cmd.focus_file_explorer_desc",
730 action: || Action::FocusFileExplorer,
731 contexts: &[Normal, Terminal],
732 custom_contexts: &[],
733 },
734 CommandDef {
735 name_key: "cmd.focus_editor",
736 desc_key: "cmd.focus_editor_desc",
737 action: || Action::FocusEditor,
738 contexts: &[FileExplorer],
739 custom_contexts: &[],
740 },
741 CommandDef {
742 name_key: "cmd.explorer_refresh",
743 desc_key: "cmd.explorer_refresh_desc",
744 action: || Action::FileExplorerRefresh,
745 contexts: &[FileExplorer],
746 custom_contexts: &[],
747 },
748 CommandDef {
749 name_key: "cmd.explorer_new_file",
750 desc_key: "cmd.explorer_new_file_desc",
751 action: || Action::FileExplorerNewFile,
752 contexts: &[FileExplorer],
753 custom_contexts: &[],
754 },
755 CommandDef {
756 name_key: "cmd.explorer_new_directory",
757 desc_key: "cmd.explorer_new_directory_desc",
758 action: || Action::FileExplorerNewDirectory,
759 contexts: &[FileExplorer],
760 custom_contexts: &[],
761 },
762 CommandDef {
763 name_key: "cmd.explorer_delete",
764 desc_key: "cmd.explorer_delete_desc",
765 action: || Action::FileExplorerDelete,
766 contexts: &[FileExplorer],
767 custom_contexts: &[],
768 },
769 CommandDef {
770 name_key: "cmd.explorer_rename",
771 desc_key: "cmd.explorer_rename_desc",
772 action: || Action::FileExplorerRename,
773 contexts: &[FileExplorer],
774 custom_contexts: &[],
775 },
776 CommandDef {
777 name_key: "cmd.toggle_hidden_files",
778 desc_key: "cmd.toggle_hidden_files_desc",
779 action: || Action::FileExplorerToggleHidden,
780 contexts: &[FileExplorer],
781 custom_contexts: &[],
782 },
783 CommandDef {
784 name_key: "cmd.toggle_gitignored_files",
785 desc_key: "cmd.toggle_gitignored_files_desc",
786 action: || Action::FileExplorerToggleGitignored,
787 contexts: &[FileExplorer],
788 custom_contexts: &[],
789 },
790 CommandDef {
792 name_key: "cmd.toggle_line_wrap",
793 desc_key: "cmd.toggle_line_wrap_desc",
794 action: || Action::ToggleLineWrap,
795 contexts: &[Normal],
796 custom_contexts: &[],
797 },
798 CommandDef {
799 name_key: "cmd.toggle_read_only",
800 desc_key: "cmd.toggle_read_only_desc",
801 action: || Action::ToggleReadOnly,
802 contexts: &[Normal],
803 custom_contexts: &[],
804 },
805 CommandDef {
806 name_key: "cmd.set_background",
807 desc_key: "cmd.set_background_desc",
808 action: || Action::SetBackground,
809 contexts: &[Normal],
810 custom_contexts: &[],
811 },
812 CommandDef {
813 name_key: "cmd.set_background_blend",
814 desc_key: "cmd.set_background_blend_desc",
815 action: || Action::SetBackgroundBlend,
816 contexts: &[Normal],
817 custom_contexts: &[],
818 },
819 CommandDef {
821 name_key: "cmd.search",
822 desc_key: "cmd.search_desc",
823 action: || Action::Search,
824 contexts: &[Normal],
825 custom_contexts: &[],
826 },
827 CommandDef {
828 name_key: "cmd.find_in_selection",
829 desc_key: "cmd.find_in_selection_desc",
830 action: || Action::FindInSelection,
831 contexts: &[Normal],
832 custom_contexts: &[],
833 },
834 CommandDef {
835 name_key: "cmd.find_next",
836 desc_key: "cmd.find_next_desc",
837 action: || Action::FindNext,
838 contexts: &[Normal],
839 custom_contexts: &[],
840 },
841 CommandDef {
842 name_key: "cmd.find_previous",
843 desc_key: "cmd.find_previous_desc",
844 action: || Action::FindPrevious,
845 contexts: &[Normal],
846 custom_contexts: &[],
847 },
848 CommandDef {
849 name_key: "cmd.find_selection_next",
850 desc_key: "cmd.find_selection_next_desc",
851 action: || Action::FindSelectionNext,
852 contexts: &[Normal],
853 custom_contexts: &[],
854 },
855 CommandDef {
856 name_key: "cmd.find_selection_previous",
857 desc_key: "cmd.find_selection_previous_desc",
858 action: || Action::FindSelectionPrevious,
859 contexts: &[Normal],
860 custom_contexts: &[],
861 },
862 CommandDef {
863 name_key: "cmd.replace",
864 desc_key: "cmd.replace_desc",
865 action: || Action::Replace,
866 contexts: &[Normal],
867 custom_contexts: &[],
868 },
869 CommandDef {
870 name_key: "cmd.query_replace",
871 desc_key: "cmd.query_replace_desc",
872 action: || Action::QueryReplace,
873 contexts: &[Normal],
874 custom_contexts: &[],
875 },
876 CommandDef {
878 name_key: "cmd.goto_line",
879 desc_key: "cmd.goto_line_desc",
880 action: || Action::GotoLine,
881 contexts: &[Normal],
882 custom_contexts: &[],
883 },
884 CommandDef {
885 name_key: "cmd.scan_line_index",
886 desc_key: "cmd.scan_line_index_desc",
887 action: || Action::ScanLineIndex,
888 contexts: &[Normal],
889 custom_contexts: &[],
890 },
891 CommandDef {
892 name_key: "cmd.smart_home",
893 desc_key: "cmd.smart_home_desc",
894 action: || Action::SmartHome,
895 contexts: &[Normal],
896 custom_contexts: &[],
897 },
898 CommandDef {
899 name_key: "cmd.show_completions",
900 desc_key: "cmd.show_completions_desc",
901 action: || Action::LspCompletion,
902 contexts: &[Normal],
903 custom_contexts: &[],
904 },
905 CommandDef {
906 name_key: "cmd.goto_definition",
907 desc_key: "cmd.goto_definition_desc",
908 action: || Action::LspGotoDefinition,
909 contexts: &[Normal],
910 custom_contexts: &[],
911 },
912 CommandDef {
913 name_key: "cmd.show_hover_info",
914 desc_key: "cmd.show_hover_info_desc",
915 action: || Action::LspHover,
916 contexts: &[Normal],
917 custom_contexts: &[],
918 },
919 CommandDef {
920 name_key: "cmd.find_references",
921 desc_key: "cmd.find_references_desc",
922 action: || Action::LspReferences,
923 contexts: &[Normal],
924 custom_contexts: &[],
925 },
926 CommandDef {
927 name_key: "cmd.show_signature_help",
928 desc_key: "cmd.show_signature_help_desc",
929 action: || Action::LspSignatureHelp,
930 contexts: &[Normal],
931 custom_contexts: &[],
932 },
933 CommandDef {
934 name_key: "cmd.code_actions",
935 desc_key: "cmd.code_actions_desc",
936 action: || Action::LspCodeActions,
937 contexts: &[Normal],
938 custom_contexts: &[],
939 },
940 CommandDef {
941 name_key: "cmd.start_restart_lsp",
942 desc_key: "cmd.start_restart_lsp_desc",
943 action: || Action::LspRestart,
944 contexts: &[Normal],
945 custom_contexts: &[],
946 },
947 CommandDef {
948 name_key: "cmd.stop_lsp",
949 desc_key: "cmd.stop_lsp_desc",
950 action: || Action::LspStop,
951 contexts: &[Normal],
952 custom_contexts: &[],
953 },
954 CommandDef {
955 name_key: "cmd.toggle_lsp_for_buffer",
956 desc_key: "cmd.toggle_lsp_for_buffer_desc",
957 action: || Action::LspToggleForBuffer,
958 contexts: &[Normal],
959 custom_contexts: &[],
960 },
961 CommandDef {
962 name_key: "cmd.toggle_mouse_hover",
963 desc_key: "cmd.toggle_mouse_hover_desc",
964 action: || Action::ToggleMouseHover,
965 contexts: &[],
966 custom_contexts: &[],
967 },
968 CommandDef {
969 name_key: "cmd.navigate_back",
970 desc_key: "cmd.navigate_back_desc",
971 action: || Action::NavigateBack,
972 contexts: &[Normal],
973 custom_contexts: &[],
974 },
975 CommandDef {
976 name_key: "cmd.navigate_forward",
977 desc_key: "cmd.navigate_forward_desc",
978 action: || Action::NavigateForward,
979 contexts: &[Normal],
980 custom_contexts: &[],
981 },
982 CommandDef {
984 name_key: "cmd.toggle_comment",
985 desc_key: "cmd.toggle_comment_desc",
986 action: || Action::ToggleComment,
987 contexts: &[Normal],
988 custom_contexts: &[],
989 },
990 CommandDef {
991 name_key: "cmd.dedent_selection",
992 desc_key: "cmd.dedent_selection_desc",
993 action: || Action::DedentSelection,
994 contexts: &[Normal],
995 custom_contexts: &[],
996 },
997 CommandDef {
998 name_key: "cmd.goto_matching_bracket",
999 desc_key: "cmd.goto_matching_bracket_desc",
1000 action: || Action::GoToMatchingBracket,
1001 contexts: &[Normal],
1002 custom_contexts: &[],
1003 },
1004 CommandDef {
1006 name_key: "cmd.jump_to_next_error",
1007 desc_key: "cmd.jump_to_next_error_desc",
1008 action: || Action::JumpToNextError,
1009 contexts: &[Normal],
1010 custom_contexts: &[],
1011 },
1012 CommandDef {
1013 name_key: "cmd.jump_to_previous_error",
1014 desc_key: "cmd.jump_to_previous_error_desc",
1015 action: || Action::JumpToPreviousError,
1016 contexts: &[Normal],
1017 custom_contexts: &[],
1018 },
1019 CommandDef {
1021 name_key: "cmd.rename_symbol",
1022 desc_key: "cmd.rename_symbol_desc",
1023 action: || Action::LspRename,
1024 contexts: &[Normal],
1025 custom_contexts: &[],
1026 },
1027 CommandDef {
1029 name_key: "cmd.list_bookmarks",
1030 desc_key: "cmd.list_bookmarks_desc",
1031 action: || Action::ListBookmarks,
1032 contexts: &[Normal],
1033 custom_contexts: &[],
1034 },
1035 CommandDef {
1036 name_key: "cmd.list_macros",
1037 desc_key: "cmd.list_macros_desc",
1038 action: || Action::ListMacros,
1039 contexts: &[Normal],
1040 custom_contexts: &[],
1041 },
1042 CommandDef {
1043 name_key: "cmd.record_macro",
1044 desc_key: "cmd.record_macro_desc",
1045 action: || Action::PromptRecordMacro,
1046 contexts: &[Normal],
1047 custom_contexts: &[],
1048 },
1049 CommandDef {
1050 name_key: "cmd.stop_recording_macro",
1051 desc_key: "cmd.stop_recording_macro_desc",
1052 action: || Action::StopMacroRecording,
1053 contexts: &[Normal],
1054 custom_contexts: &[],
1055 },
1056 CommandDef {
1057 name_key: "cmd.play_macro",
1058 desc_key: "cmd.play_macro_desc",
1059 action: || Action::PromptPlayMacro,
1060 contexts: &[Normal],
1061 custom_contexts: &[],
1062 },
1063 CommandDef {
1064 name_key: "cmd.play_last_macro",
1065 desc_key: "cmd.play_last_macro_desc",
1066 action: || Action::PlayLastMacro,
1067 contexts: &[Normal],
1068 custom_contexts: &[],
1069 },
1070 CommandDef {
1071 name_key: "cmd.set_bookmark",
1072 desc_key: "cmd.set_bookmark_desc",
1073 action: || Action::PromptSetBookmark,
1074 contexts: &[Normal],
1075 custom_contexts: &[],
1076 },
1077 CommandDef {
1078 name_key: "cmd.jump_to_bookmark",
1079 desc_key: "cmd.jump_to_bookmark_desc",
1080 action: || Action::PromptJumpToBookmark,
1081 contexts: &[Normal],
1082 custom_contexts: &[],
1083 },
1084 CommandDef {
1086 name_key: "cmd.show_manual",
1087 desc_key: "cmd.show_manual_desc",
1088 action: || Action::ShowHelp,
1089 contexts: &[],
1090 custom_contexts: &[],
1091 },
1092 CommandDef {
1093 name_key: "cmd.show_keyboard_shortcuts",
1094 desc_key: "cmd.show_keyboard_shortcuts_desc",
1095 action: || Action::ShowKeyboardShortcuts,
1096 contexts: &[],
1097 custom_contexts: &[],
1098 },
1099 CommandDef {
1100 name_key: "cmd.show_warnings",
1101 desc_key: "cmd.show_warnings_desc",
1102 action: || Action::ShowWarnings,
1103 contexts: &[],
1104 custom_contexts: &[],
1105 },
1106 CommandDef {
1107 name_key: "cmd.show_lsp_status",
1108 desc_key: "cmd.show_lsp_status_desc",
1109 action: || Action::ShowLspStatus,
1110 contexts: &[],
1111 custom_contexts: &[],
1112 },
1113 CommandDef {
1114 name_key: "cmd.clear_warnings",
1115 desc_key: "cmd.clear_warnings_desc",
1116 action: || Action::ClearWarnings,
1117 contexts: &[],
1118 custom_contexts: &[],
1119 },
1120 CommandDef {
1122 name_key: "cmd.dump_config",
1123 desc_key: "cmd.dump_config_desc",
1124 action: || Action::DumpConfig,
1125 contexts: &[],
1126 custom_contexts: &[],
1127 },
1128 CommandDef {
1129 name_key: "cmd.toggle_inlay_hints",
1130 desc_key: "cmd.toggle_inlay_hints_desc",
1131 action: || Action::ToggleInlayHints,
1132 contexts: &[Normal],
1133 custom_contexts: &[],
1134 },
1135 CommandDef {
1137 name_key: "cmd.select_theme",
1138 desc_key: "cmd.select_theme_desc",
1139 action: || Action::SelectTheme,
1140 contexts: &[],
1141 custom_contexts: &[],
1142 },
1143 CommandDef {
1145 name_key: "cmd.inspect_theme_at_cursor",
1146 desc_key: "cmd.inspect_theme_at_cursor_desc",
1147 action: || Action::InspectThemeAtCursor,
1148 contexts: &[Normal],
1149 custom_contexts: &[],
1150 },
1151 CommandDef {
1153 name_key: "cmd.select_keybinding_map",
1154 desc_key: "cmd.select_keybinding_map_desc",
1155 action: || Action::SelectKeybindingMap,
1156 contexts: &[],
1157 custom_contexts: &[],
1158 },
1159 CommandDef {
1161 name_key: "cmd.select_cursor_style",
1162 desc_key: "cmd.select_cursor_style_desc",
1163 action: || Action::SelectCursorStyle,
1164 contexts: &[],
1165 custom_contexts: &[],
1166 },
1167 CommandDef {
1169 name_key: "cmd.select_locale",
1170 desc_key: "cmd.select_locale_desc",
1171 action: || Action::SelectLocale,
1172 contexts: &[],
1173 custom_contexts: &[],
1174 },
1175 CommandDef {
1177 name_key: "cmd.open_settings",
1178 desc_key: "cmd.open_settings_desc",
1179 action: || Action::OpenSettings,
1180 contexts: &[],
1181 custom_contexts: &[],
1182 },
1183 CommandDef {
1185 name_key: "cmd.open_keybinding_editor",
1186 desc_key: "cmd.open_keybinding_editor_desc",
1187 action: || Action::OpenKeybindingEditor,
1188 contexts: &[],
1189 custom_contexts: &[],
1190 },
1191 CommandDef {
1193 name_key: "cmd.calibrate_input",
1194 desc_key: "cmd.calibrate_input_desc",
1195 action: || Action::CalibrateInput,
1196 contexts: &[],
1197 custom_contexts: &[],
1198 },
1199 CommandDef {
1201 name_key: "cmd.open_terminal",
1202 desc_key: "cmd.open_terminal_desc",
1203 action: || Action::OpenTerminal,
1204 contexts: &[],
1205 custom_contexts: &[],
1206 },
1207 CommandDef {
1208 name_key: "cmd.focus_terminal",
1209 desc_key: "cmd.focus_terminal_desc",
1210 action: || Action::FocusTerminal,
1211 contexts: &[Normal],
1212 custom_contexts: &[],
1213 },
1214 CommandDef {
1215 name_key: "cmd.exit_terminal_mode",
1216 desc_key: "cmd.exit_terminal_mode_desc",
1217 action: || Action::TerminalEscape,
1218 contexts: &[Terminal],
1219 custom_contexts: &[],
1220 },
1221 CommandDef {
1222 name_key: "cmd.toggle_keyboard_capture",
1223 desc_key: "cmd.toggle_keyboard_capture_desc",
1224 action: || Action::ToggleKeyboardCapture,
1225 contexts: &[Terminal],
1226 custom_contexts: &[],
1227 },
1228 CommandDef {
1230 name_key: "cmd.shell_command",
1231 desc_key: "cmd.shell_command_desc",
1232 action: || Action::ShellCommand,
1233 contexts: &[Normal],
1234 custom_contexts: &[],
1235 },
1236 CommandDef {
1237 name_key: "cmd.shell_command_replace",
1238 desc_key: "cmd.shell_command_replace_desc",
1239 action: || Action::ShellCommandReplace,
1240 contexts: &[Normal],
1241 custom_contexts: &[],
1242 },
1243 CommandDef {
1245 name_key: "cmd.event_debug",
1246 desc_key: "cmd.event_debug_desc",
1247 action: || Action::EventDebug,
1248 contexts: &[],
1249 custom_contexts: &[],
1250 },
1251 CommandDef {
1253 name_key: "cmd.load_plugin_from_buffer",
1254 desc_key: "cmd.load_plugin_from_buffer_desc",
1255 action: || Action::LoadPluginFromBuffer,
1256 contexts: &[Normal],
1257 custom_contexts: &[],
1258 },
1259];
1260
1261pub fn get_all_commands() -> Vec<Command> {
1263 COMMAND_DEFS
1264 .iter()
1265 .map(|def| Command {
1266 name: t!(def.name_key).to_string(),
1267 description: t!(def.desc_key).to_string(),
1268 action: (def.action)(),
1269 contexts: def.contexts.to_vec(),
1270 custom_contexts: def.custom_contexts.iter().map(|s| s.to_string()).collect(),
1271 source: CommandSource::Builtin,
1272 })
1273 .collect()
1274}
1275
1276pub fn filter_commands(
1278 query: &str,
1279 current_context: KeyContext,
1280 keybinding_resolver: &crate::input::keybindings::KeybindingResolver,
1281) -> Vec<Suggestion> {
1282 let query_lower = query.to_lowercase();
1283 let commands = get_all_commands();
1284
1285 let is_available = |cmd: &Command| -> bool {
1287 cmd.contexts.is_empty() || cmd.contexts.contains(¤t_context)
1289 };
1290
1291 let matches_query = |cmd: &Command| -> bool {
1293 if query.is_empty() {
1294 return true;
1295 }
1296
1297 let name_lower = cmd.name.to_lowercase();
1298 let mut query_chars = query_lower.chars();
1299 let mut current_char = query_chars.next();
1300
1301 for name_char in name_lower.chars() {
1302 if let Some(qc) = current_char {
1303 if qc == name_char {
1304 current_char = query_chars.next();
1305 }
1306 } else {
1307 break;
1308 }
1309 }
1310
1311 current_char.is_none() };
1313
1314 let mut suggestions: Vec<Suggestion> = commands
1316 .into_iter()
1317 .filter(|cmd| matches_query(cmd))
1318 .map(|cmd| {
1319 let available = is_available(&cmd);
1320 let keybinding =
1321 keybinding_resolver.get_keybinding_for_action(&cmd.action, current_context);
1322 Suggestion::with_all(
1323 cmd.name.clone(),
1324 Some(cmd.description),
1325 !available,
1326 keybinding,
1327 )
1328 })
1329 .collect();
1330
1331 suggestions.sort_by_key(|s| s.disabled);
1333
1334 suggestions
1335}