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