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_prompt_line",
715 desc_key: "cmd.toggle_prompt_line_desc",
716 action: || Action::TogglePromptLine,
717 contexts: &[Normal, FileExplorer, Terminal],
718 custom_contexts: &[],
719 },
720 CommandDef {
721 name_key: "cmd.toggle_vertical_scrollbar",
722 desc_key: "cmd.toggle_vertical_scrollbar_desc",
723 action: || Action::ToggleVerticalScrollbar,
724 contexts: &[Normal, FileExplorer, Terminal],
725 custom_contexts: &[],
726 },
727 CommandDef {
728 name_key: "cmd.toggle_horizontal_scrollbar",
729 desc_key: "cmd.toggle_horizontal_scrollbar_desc",
730 action: || Action::ToggleHorizontalScrollbar,
731 contexts: &[Normal, FileExplorer, Terminal],
732 custom_contexts: &[],
733 },
734 CommandDef {
735 name_key: "cmd.focus_file_explorer",
736 desc_key: "cmd.focus_file_explorer_desc",
737 action: || Action::FocusFileExplorer,
738 contexts: &[Normal, Terminal],
739 custom_contexts: &[],
740 },
741 CommandDef {
742 name_key: "cmd.focus_editor",
743 desc_key: "cmd.focus_editor_desc",
744 action: || Action::FocusEditor,
745 contexts: &[FileExplorer],
746 custom_contexts: &[],
747 },
748 CommandDef {
749 name_key: "cmd.explorer_refresh",
750 desc_key: "cmd.explorer_refresh_desc",
751 action: || Action::FileExplorerRefresh,
752 contexts: &[FileExplorer],
753 custom_contexts: &[],
754 },
755 CommandDef {
756 name_key: "cmd.explorer_new_file",
757 desc_key: "cmd.explorer_new_file_desc",
758 action: || Action::FileExplorerNewFile,
759 contexts: &[FileExplorer],
760 custom_contexts: &[],
761 },
762 CommandDef {
763 name_key: "cmd.explorer_new_directory",
764 desc_key: "cmd.explorer_new_directory_desc",
765 action: || Action::FileExplorerNewDirectory,
766 contexts: &[FileExplorer],
767 custom_contexts: &[],
768 },
769 CommandDef {
770 name_key: "cmd.explorer_delete",
771 desc_key: "cmd.explorer_delete_desc",
772 action: || Action::FileExplorerDelete,
773 contexts: &[FileExplorer],
774 custom_contexts: &[],
775 },
776 CommandDef {
777 name_key: "cmd.explorer_rename",
778 desc_key: "cmd.explorer_rename_desc",
779 action: || Action::FileExplorerRename,
780 contexts: &[FileExplorer],
781 custom_contexts: &[],
782 },
783 CommandDef {
784 name_key: "cmd.toggle_hidden_files",
785 desc_key: "cmd.toggle_hidden_files_desc",
786 action: || Action::FileExplorerToggleHidden,
787 contexts: &[FileExplorer],
788 custom_contexts: &[],
789 },
790 CommandDef {
791 name_key: "cmd.toggle_gitignored_files",
792 desc_key: "cmd.toggle_gitignored_files_desc",
793 action: || Action::FileExplorerToggleGitignored,
794 contexts: &[FileExplorer],
795 custom_contexts: &[],
796 },
797 CommandDef {
799 name_key: "cmd.toggle_line_wrap",
800 desc_key: "cmd.toggle_line_wrap_desc",
801 action: || Action::ToggleLineWrap,
802 contexts: &[Normal],
803 custom_contexts: &[],
804 },
805 CommandDef {
806 name_key: "cmd.toggle_current_line_highlight",
807 desc_key: "cmd.toggle_current_line_highlight_desc",
808 action: || Action::ToggleCurrentLineHighlight,
809 contexts: &[Normal],
810 custom_contexts: &[],
811 },
812 CommandDef {
813 name_key: "cmd.toggle_page_view",
814 desc_key: "cmd.toggle_page_view_desc",
815 action: || Action::TogglePageView,
816 contexts: &[Normal],
817 custom_contexts: &[],
818 },
819 CommandDef {
820 name_key: "cmd.set_page_width",
821 desc_key: "cmd.set_page_width_desc",
822 action: || Action::SetPageWidth,
823 contexts: &[Normal],
824 custom_contexts: &[],
825 },
826 CommandDef {
827 name_key: "cmd.toggle_read_only",
828 desc_key: "cmd.toggle_read_only_desc",
829 action: || Action::ToggleReadOnly,
830 contexts: &[Normal],
831 custom_contexts: &[],
832 },
833 CommandDef {
834 name_key: "cmd.set_background",
835 desc_key: "cmd.set_background_desc",
836 action: || Action::SetBackground,
837 contexts: &[Normal],
838 custom_contexts: &[],
839 },
840 CommandDef {
841 name_key: "cmd.set_background_blend",
842 desc_key: "cmd.set_background_blend_desc",
843 action: || Action::SetBackgroundBlend,
844 contexts: &[Normal],
845 custom_contexts: &[],
846 },
847 CommandDef {
849 name_key: "cmd.search",
850 desc_key: "cmd.search_desc",
851 action: || Action::Search,
852 contexts: &[Normal],
853 custom_contexts: &[],
854 },
855 CommandDef {
856 name_key: "cmd.find_in_selection",
857 desc_key: "cmd.find_in_selection_desc",
858 action: || Action::FindInSelection,
859 contexts: &[Normal],
860 custom_contexts: &[],
861 },
862 CommandDef {
863 name_key: "cmd.find_next",
864 desc_key: "cmd.find_next_desc",
865 action: || Action::FindNext,
866 contexts: &[Normal],
867 custom_contexts: &[],
868 },
869 CommandDef {
870 name_key: "cmd.find_previous",
871 desc_key: "cmd.find_previous_desc",
872 action: || Action::FindPrevious,
873 contexts: &[Normal],
874 custom_contexts: &[],
875 },
876 CommandDef {
877 name_key: "cmd.find_selection_next",
878 desc_key: "cmd.find_selection_next_desc",
879 action: || Action::FindSelectionNext,
880 contexts: &[Normal],
881 custom_contexts: &[],
882 },
883 CommandDef {
884 name_key: "cmd.find_selection_previous",
885 desc_key: "cmd.find_selection_previous_desc",
886 action: || Action::FindSelectionPrevious,
887 contexts: &[Normal],
888 custom_contexts: &[],
889 },
890 CommandDef {
891 name_key: "cmd.replace",
892 desc_key: "cmd.replace_desc",
893 action: || Action::Replace,
894 contexts: &[Normal],
895 custom_contexts: &[],
896 },
897 CommandDef {
898 name_key: "cmd.query_replace",
899 desc_key: "cmd.query_replace_desc",
900 action: || Action::QueryReplace,
901 contexts: &[Normal],
902 custom_contexts: &[],
903 },
904 CommandDef {
906 name_key: "cmd.goto_line",
907 desc_key: "cmd.goto_line_desc",
908 action: || Action::GotoLine,
909 contexts: &[Normal],
910 custom_contexts: &[],
911 },
912 CommandDef {
913 name_key: "cmd.scan_line_index",
914 desc_key: "cmd.scan_line_index_desc",
915 action: || Action::ScanLineIndex,
916 contexts: &[Normal],
917 custom_contexts: &[],
918 },
919 CommandDef {
920 name_key: "cmd.smart_home",
921 desc_key: "cmd.smart_home_desc",
922 action: || Action::SmartHome,
923 contexts: &[Normal],
924 custom_contexts: &[],
925 },
926 CommandDef {
927 name_key: "cmd.show_completions",
928 desc_key: "cmd.show_completions_desc",
929 action: || Action::LspCompletion,
930 contexts: &[Normal],
931 custom_contexts: &[],
932 },
933 CommandDef {
934 name_key: "cmd.goto_definition",
935 desc_key: "cmd.goto_definition_desc",
936 action: || Action::LspGotoDefinition,
937 contexts: &[Normal],
938 custom_contexts: &[],
939 },
940 CommandDef {
941 name_key: "cmd.show_hover_info",
942 desc_key: "cmd.show_hover_info_desc",
943 action: || Action::LspHover,
944 contexts: &[Normal],
945 custom_contexts: &[],
946 },
947 CommandDef {
948 name_key: "cmd.find_references",
949 desc_key: "cmd.find_references_desc",
950 action: || Action::LspReferences,
951 contexts: &[Normal],
952 custom_contexts: &[],
953 },
954 CommandDef {
955 name_key: "cmd.show_signature_help",
956 desc_key: "cmd.show_signature_help_desc",
957 action: || Action::LspSignatureHelp,
958 contexts: &[Normal],
959 custom_contexts: &[],
960 },
961 CommandDef {
962 name_key: "cmd.code_actions",
963 desc_key: "cmd.code_actions_desc",
964 action: || Action::LspCodeActions,
965 contexts: &[Normal],
966 custom_contexts: &[],
967 },
968 CommandDef {
969 name_key: "cmd.start_restart_lsp",
970 desc_key: "cmd.start_restart_lsp_desc",
971 action: || Action::LspRestart,
972 contexts: &[Normal],
973 custom_contexts: &[],
974 },
975 CommandDef {
976 name_key: "cmd.stop_lsp",
977 desc_key: "cmd.stop_lsp_desc",
978 action: || Action::LspStop,
979 contexts: &[Normal],
980 custom_contexts: &[],
981 },
982 CommandDef {
983 name_key: "cmd.toggle_lsp_for_buffer",
984 desc_key: "cmd.toggle_lsp_for_buffer_desc",
985 action: || Action::LspToggleForBuffer,
986 contexts: &[Normal],
987 custom_contexts: &[],
988 },
989 CommandDef {
990 name_key: "cmd.toggle_mouse_hover",
991 desc_key: "cmd.toggle_mouse_hover_desc",
992 action: || Action::ToggleMouseHover,
993 contexts: &[],
994 custom_contexts: &[],
995 },
996 CommandDef {
997 name_key: "cmd.navigate_back",
998 desc_key: "cmd.navigate_back_desc",
999 action: || Action::NavigateBack,
1000 contexts: &[Normal],
1001 custom_contexts: &[],
1002 },
1003 CommandDef {
1004 name_key: "cmd.navigate_forward",
1005 desc_key: "cmd.navigate_forward_desc",
1006 action: || Action::NavigateForward,
1007 contexts: &[Normal],
1008 custom_contexts: &[],
1009 },
1010 CommandDef {
1012 name_key: "cmd.toggle_comment",
1013 desc_key: "cmd.toggle_comment_desc",
1014 action: || Action::ToggleComment,
1015 contexts: &[Normal],
1016 custom_contexts: &[],
1017 },
1018 CommandDef {
1019 name_key: "cmd.dedent_selection",
1020 desc_key: "cmd.dedent_selection_desc",
1021 action: || Action::DedentSelection,
1022 contexts: &[Normal],
1023 custom_contexts: &[],
1024 },
1025 CommandDef {
1026 name_key: "cmd.goto_matching_bracket",
1027 desc_key: "cmd.goto_matching_bracket_desc",
1028 action: || Action::GoToMatchingBracket,
1029 contexts: &[Normal],
1030 custom_contexts: &[],
1031 },
1032 CommandDef {
1034 name_key: "cmd.jump_to_next_error",
1035 desc_key: "cmd.jump_to_next_error_desc",
1036 action: || Action::JumpToNextError,
1037 contexts: &[Normal],
1038 custom_contexts: &[],
1039 },
1040 CommandDef {
1041 name_key: "cmd.jump_to_previous_error",
1042 desc_key: "cmd.jump_to_previous_error_desc",
1043 action: || Action::JumpToPreviousError,
1044 contexts: &[Normal],
1045 custom_contexts: &[],
1046 },
1047 CommandDef {
1049 name_key: "cmd.rename_symbol",
1050 desc_key: "cmd.rename_symbol_desc",
1051 action: || Action::LspRename,
1052 contexts: &[Normal],
1053 custom_contexts: &[],
1054 },
1055 CommandDef {
1057 name_key: "cmd.list_bookmarks",
1058 desc_key: "cmd.list_bookmarks_desc",
1059 action: || Action::ListBookmarks,
1060 contexts: &[Normal],
1061 custom_contexts: &[],
1062 },
1063 CommandDef {
1064 name_key: "cmd.list_macros",
1065 desc_key: "cmd.list_macros_desc",
1066 action: || Action::ListMacros,
1067 contexts: &[Normal],
1068 custom_contexts: &[],
1069 },
1070 CommandDef {
1071 name_key: "cmd.record_macro",
1072 desc_key: "cmd.record_macro_desc",
1073 action: || Action::PromptRecordMacro,
1074 contexts: &[Normal],
1075 custom_contexts: &[],
1076 },
1077 CommandDef {
1078 name_key: "cmd.stop_recording_macro",
1079 desc_key: "cmd.stop_recording_macro_desc",
1080 action: || Action::StopMacroRecording,
1081 contexts: &[Normal],
1082 custom_contexts: &[],
1083 },
1084 CommandDef {
1085 name_key: "cmd.play_macro",
1086 desc_key: "cmd.play_macro_desc",
1087 action: || Action::PromptPlayMacro,
1088 contexts: &[Normal],
1089 custom_contexts: &[],
1090 },
1091 CommandDef {
1092 name_key: "cmd.play_last_macro",
1093 desc_key: "cmd.play_last_macro_desc",
1094 action: || Action::PlayLastMacro,
1095 contexts: &[Normal],
1096 custom_contexts: &[],
1097 },
1098 CommandDef {
1099 name_key: "cmd.set_bookmark",
1100 desc_key: "cmd.set_bookmark_desc",
1101 action: || Action::PromptSetBookmark,
1102 contexts: &[Normal],
1103 custom_contexts: &[],
1104 },
1105 CommandDef {
1106 name_key: "cmd.jump_to_bookmark",
1107 desc_key: "cmd.jump_to_bookmark_desc",
1108 action: || Action::PromptJumpToBookmark,
1109 contexts: &[Normal],
1110 custom_contexts: &[],
1111 },
1112 CommandDef {
1114 name_key: "cmd.show_manual",
1115 desc_key: "cmd.show_manual_desc",
1116 action: || Action::ShowHelp,
1117 contexts: &[],
1118 custom_contexts: &[],
1119 },
1120 CommandDef {
1121 name_key: "cmd.show_keyboard_shortcuts",
1122 desc_key: "cmd.show_keyboard_shortcuts_desc",
1123 action: || Action::ShowKeyboardShortcuts,
1124 contexts: &[],
1125 custom_contexts: &[],
1126 },
1127 CommandDef {
1128 name_key: "cmd.show_warnings",
1129 desc_key: "cmd.show_warnings_desc",
1130 action: || Action::ShowWarnings,
1131 contexts: &[],
1132 custom_contexts: &[],
1133 },
1134 CommandDef {
1135 name_key: "cmd.show_lsp_status",
1136 desc_key: "cmd.show_lsp_status_desc",
1137 action: || Action::ShowLspStatus,
1138 contexts: &[],
1139 custom_contexts: &[],
1140 },
1141 CommandDef {
1142 name_key: "cmd.clear_warnings",
1143 desc_key: "cmd.clear_warnings_desc",
1144 action: || Action::ClearWarnings,
1145 contexts: &[],
1146 custom_contexts: &[],
1147 },
1148 CommandDef {
1150 name_key: "cmd.dump_config",
1151 desc_key: "cmd.dump_config_desc",
1152 action: || Action::DumpConfig,
1153 contexts: &[],
1154 custom_contexts: &[],
1155 },
1156 CommandDef {
1157 name_key: "cmd.toggle_inlay_hints",
1158 desc_key: "cmd.toggle_inlay_hints_desc",
1159 action: || Action::ToggleInlayHints,
1160 contexts: &[Normal],
1161 custom_contexts: &[],
1162 },
1163 CommandDef {
1165 name_key: "cmd.select_theme",
1166 desc_key: "cmd.select_theme_desc",
1167 action: || Action::SelectTheme,
1168 contexts: &[],
1169 custom_contexts: &[],
1170 },
1171 CommandDef {
1173 name_key: "cmd.inspect_theme_at_cursor",
1174 desc_key: "cmd.inspect_theme_at_cursor_desc",
1175 action: || Action::InspectThemeAtCursor,
1176 contexts: &[Normal],
1177 custom_contexts: &[],
1178 },
1179 CommandDef {
1181 name_key: "cmd.select_keybinding_map",
1182 desc_key: "cmd.select_keybinding_map_desc",
1183 action: || Action::SelectKeybindingMap,
1184 contexts: &[],
1185 custom_contexts: &[],
1186 },
1187 CommandDef {
1189 name_key: "cmd.select_cursor_style",
1190 desc_key: "cmd.select_cursor_style_desc",
1191 action: || Action::SelectCursorStyle,
1192 contexts: &[],
1193 custom_contexts: &[],
1194 },
1195 CommandDef {
1197 name_key: "cmd.select_locale",
1198 desc_key: "cmd.select_locale_desc",
1199 action: || Action::SelectLocale,
1200 contexts: &[],
1201 custom_contexts: &[],
1202 },
1203 CommandDef {
1205 name_key: "cmd.open_settings",
1206 desc_key: "cmd.open_settings_desc",
1207 action: || Action::OpenSettings,
1208 contexts: &[],
1209 custom_contexts: &[],
1210 },
1211 CommandDef {
1213 name_key: "cmd.open_keybinding_editor",
1214 desc_key: "cmd.open_keybinding_editor_desc",
1215 action: || Action::OpenKeybindingEditor,
1216 contexts: &[],
1217 custom_contexts: &[],
1218 },
1219 CommandDef {
1221 name_key: "cmd.calibrate_input",
1222 desc_key: "cmd.calibrate_input_desc",
1223 action: || Action::CalibrateInput,
1224 contexts: &[],
1225 custom_contexts: &[],
1226 },
1227 CommandDef {
1229 name_key: "cmd.open_terminal",
1230 desc_key: "cmd.open_terminal_desc",
1231 action: || Action::OpenTerminal,
1232 contexts: &[],
1233 custom_contexts: &[],
1234 },
1235 CommandDef {
1236 name_key: "cmd.focus_terminal",
1237 desc_key: "cmd.focus_terminal_desc",
1238 action: || Action::FocusTerminal,
1239 contexts: &[Normal],
1240 custom_contexts: &[],
1241 },
1242 CommandDef {
1243 name_key: "cmd.exit_terminal_mode",
1244 desc_key: "cmd.exit_terminal_mode_desc",
1245 action: || Action::TerminalEscape,
1246 contexts: &[Terminal],
1247 custom_contexts: &[],
1248 },
1249 CommandDef {
1250 name_key: "cmd.toggle_keyboard_capture",
1251 desc_key: "cmd.toggle_keyboard_capture_desc",
1252 action: || Action::ToggleKeyboardCapture,
1253 contexts: &[Terminal],
1254 custom_contexts: &[],
1255 },
1256 CommandDef {
1258 name_key: "cmd.shell_command",
1259 desc_key: "cmd.shell_command_desc",
1260 action: || Action::ShellCommand,
1261 contexts: &[Normal],
1262 custom_contexts: &[],
1263 },
1264 CommandDef {
1265 name_key: "cmd.shell_command_replace",
1266 desc_key: "cmd.shell_command_replace_desc",
1267 action: || Action::ShellCommandReplace,
1268 contexts: &[Normal],
1269 custom_contexts: &[],
1270 },
1271 CommandDef {
1273 name_key: "cmd.event_debug",
1274 desc_key: "cmd.event_debug_desc",
1275 action: || Action::EventDebug,
1276 contexts: &[],
1277 custom_contexts: &[],
1278 },
1279 CommandDef {
1281 name_key: "cmd.load_plugin_from_buffer",
1282 desc_key: "cmd.load_plugin_from_buffer_desc",
1283 action: || Action::LoadPluginFromBuffer,
1284 contexts: &[Normal],
1285 custom_contexts: &[],
1286 },
1287];
1288
1289pub fn get_all_commands() -> Vec<Command> {
1291 COMMAND_DEFS
1292 .iter()
1293 .map(|def| Command {
1294 name: t!(def.name_key).to_string(),
1295 description: t!(def.desc_key).to_string(),
1296 action: (def.action)(),
1297 contexts: def.contexts.to_vec(),
1298 custom_contexts: def.custom_contexts.iter().map(|s| s.to_string()).collect(),
1299 source: CommandSource::Builtin,
1300 })
1301 .collect()
1302}
1303
1304pub fn filter_commands(
1306 query: &str,
1307 current_context: KeyContext,
1308 keybinding_resolver: &crate::input::keybindings::KeybindingResolver,
1309) -> Vec<Suggestion> {
1310 let query_lower = query.to_lowercase();
1311 let commands = get_all_commands();
1312
1313 let is_available = |cmd: &Command| -> bool {
1315 cmd.contexts.is_empty() || cmd.contexts.contains(¤t_context)
1317 };
1318
1319 let matches_query = |cmd: &Command| -> bool {
1321 if query.is_empty() {
1322 return true;
1323 }
1324
1325 let name_lower = cmd.name.to_lowercase();
1326 let mut query_chars = query_lower.chars();
1327 let mut current_char = query_chars.next();
1328
1329 for name_char in name_lower.chars() {
1330 if let Some(qc) = current_char {
1331 if qc == name_char {
1332 current_char = query_chars.next();
1333 }
1334 } else {
1335 break;
1336 }
1337 }
1338
1339 current_char.is_none() };
1341
1342 let current_context_ref = ¤t_context;
1344 let mut suggestions: Vec<Suggestion> = commands
1345 .into_iter()
1346 .filter(|cmd| matches_query(cmd))
1347 .map(|cmd| {
1348 let available = is_available(&cmd);
1349 let keybinding = keybinding_resolver
1350 .get_keybinding_for_action(&cmd.action, current_context_ref.clone());
1351 Suggestion::with_all(
1352 cmd.name.clone(),
1353 Some(cmd.description),
1354 !available,
1355 keybinding,
1356 )
1357 })
1358 .collect();
1359
1360 suggestions.sort_by_key(|s| s.disabled);
1362
1363 suggestions
1364}