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