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