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.next_window",
548 desc_key: "cmd.next_window_desc",
549 action: || Action::NextWindow,
550 contexts: &[],
551 custom_contexts: &[],
552 },
553 CommandDef {
554 name_key: "cmd.previous_window",
555 desc_key: "cmd.previous_window_desc",
556 action: || Action::PrevWindow,
557 contexts: &[],
558 custom_contexts: &[],
559 },
560 CommandDef {
561 name_key: "cmd.increase_split_size",
562 desc_key: "cmd.increase_split_size_desc",
563 action: || Action::IncreaseSplitSize,
564 contexts: &[Normal, Terminal],
565 custom_contexts: &[],
566 },
567 CommandDef {
568 name_key: "cmd.decrease_split_size",
569 desc_key: "cmd.decrease_split_size_desc",
570 action: || Action::DecreaseSplitSize,
571 contexts: &[Normal, Terminal],
572 custom_contexts: &[],
573 },
574 CommandDef {
575 name_key: "cmd.toggle_maximize_split",
576 desc_key: "cmd.toggle_maximize_split_desc",
577 action: || Action::ToggleMaximizeSplit,
578 contexts: &[Normal, Terminal],
579 custom_contexts: &[],
580 },
581 CommandDef {
583 name_key: "cmd.toggle_line_numbers",
584 desc_key: "cmd.toggle_line_numbers_desc",
585 action: || Action::ToggleLineNumbers,
586 contexts: &[Normal],
587 custom_contexts: &[],
588 },
589 CommandDef {
590 name_key: "cmd.toggle_scroll_sync",
591 desc_key: "cmd.toggle_scroll_sync_desc",
592 action: || Action::ToggleScrollSync,
593 contexts: &[Normal],
594 custom_contexts: &[],
595 },
596 CommandDef {
597 name_key: "cmd.toggle_fold",
598 desc_key: "cmd.toggle_fold_desc",
599 action: || Action::ToggleFold,
600 contexts: &[Normal],
601 custom_contexts: &[],
602 },
603 CommandDef {
604 name_key: "cmd.debug_toggle_highlight",
605 desc_key: "cmd.debug_toggle_highlight_desc",
606 action: || Action::ToggleDebugHighlights,
607 contexts: &[Normal],
608 custom_contexts: &[],
609 },
610 CommandDef {
612 name_key: "cmd.add_ruler",
613 desc_key: "cmd.add_ruler_desc",
614 action: || Action::AddRuler,
615 contexts: &[Normal],
616 custom_contexts: &[],
617 },
618 CommandDef {
619 name_key: "cmd.remove_ruler",
620 desc_key: "cmd.remove_ruler_desc",
621 action: || Action::RemoveRuler,
622 contexts: &[Normal],
623 custom_contexts: &[],
624 },
625 CommandDef {
627 name_key: "cmd.set_tab_size",
628 desc_key: "cmd.set_tab_size_desc",
629 action: || Action::SetTabSize,
630 contexts: &[Normal],
631 custom_contexts: &[],
632 },
633 CommandDef {
634 name_key: "cmd.set_line_ending",
635 desc_key: "cmd.set_line_ending_desc",
636 action: || Action::SetLineEnding,
637 contexts: &[Normal],
638 custom_contexts: &[],
639 },
640 CommandDef {
641 name_key: "cmd.set_encoding",
642 desc_key: "cmd.set_encoding_desc",
643 action: || Action::SetEncoding,
644 contexts: &[Normal],
645 custom_contexts: &[],
646 },
647 CommandDef {
648 name_key: "cmd.reload_with_encoding",
649 desc_key: "cmd.reload_with_encoding_desc",
650 action: || Action::ReloadWithEncoding,
651 contexts: &[Normal],
652 custom_contexts: &[],
653 },
654 CommandDef {
655 name_key: "cmd.set_language",
656 desc_key: "cmd.set_language_desc",
657 action: || Action::SetLanguage,
658 contexts: &[Normal],
659 custom_contexts: &[],
660 },
661 CommandDef {
662 name_key: "cmd.toggle_indentation",
663 desc_key: "cmd.toggle_indentation_desc",
664 action: || Action::ToggleIndentationStyle,
665 contexts: &[Normal],
666 custom_contexts: &[],
667 },
668 CommandDef {
669 name_key: "cmd.toggle_tab_indicators",
670 desc_key: "cmd.toggle_tab_indicators_desc",
671 action: || Action::ToggleTabIndicators,
672 contexts: &[Normal],
673 custom_contexts: &[],
674 },
675 CommandDef {
676 name_key: "cmd.toggle_whitespace_indicators",
677 desc_key: "cmd.toggle_whitespace_indicators_desc",
678 action: || Action::ToggleWhitespaceIndicators,
679 contexts: &[Normal],
680 custom_contexts: &[],
681 },
682 CommandDef {
683 name_key: "cmd.reset_buffer_settings",
684 desc_key: "cmd.reset_buffer_settings_desc",
685 action: || Action::ResetBufferSettings,
686 contexts: &[Normal],
687 custom_contexts: &[],
688 },
689 CommandDef {
690 name_key: "cmd.scroll_up",
691 desc_key: "cmd.scroll_up_desc",
692 action: || Action::ScrollUp,
693 contexts: &[Normal],
694 custom_contexts: &[],
695 },
696 CommandDef {
697 name_key: "cmd.scroll_down",
698 desc_key: "cmd.scroll_down_desc",
699 action: || Action::ScrollDown,
700 contexts: &[Normal],
701 custom_contexts: &[],
702 },
703 CommandDef {
704 name_key: "cmd.scroll_tabs_left",
705 desc_key: "cmd.scroll_tabs_left_desc",
706 action: || Action::ScrollTabsLeft,
707 contexts: &[Normal, Terminal],
708 custom_contexts: &[],
709 },
710 CommandDef {
711 name_key: "cmd.scroll_tabs_right",
712 desc_key: "cmd.scroll_tabs_right_desc",
713 action: || Action::ScrollTabsRight,
714 contexts: &[Normal, Terminal],
715 custom_contexts: &[],
716 },
717 CommandDef {
718 name_key: "cmd.toggle_mouse_support",
719 desc_key: "cmd.toggle_mouse_support_desc",
720 action: || Action::ToggleMouseCapture,
721 contexts: &[Normal, Terminal],
722 custom_contexts: &[],
723 },
724 CommandDef {
726 name_key: "cmd.toggle_file_explorer",
727 desc_key: "cmd.toggle_file_explorer_desc",
728 action: || Action::ToggleFileExplorer,
729 contexts: &[Normal, FileExplorer, Terminal],
730 custom_contexts: &[],
731 },
732 CommandDef {
733 name_key: "cmd.toggle_file_explorer_side",
734 desc_key: "cmd.toggle_file_explorer_side_desc",
735 action: || Action::ToggleFileExplorerSide,
736 contexts: &[Normal, FileExplorer, Terminal],
737 custom_contexts: &[],
738 },
739 CommandDef {
740 name_key: "cmd.toggle_menu_bar",
741 desc_key: "cmd.toggle_menu_bar_desc",
742 action: || Action::ToggleMenuBar,
743 contexts: &[Normal, FileExplorer, Terminal],
744 custom_contexts: &[],
745 },
746 CommandDef {
747 name_key: "cmd.toggle_tab_bar",
748 desc_key: "cmd.toggle_tab_bar_desc",
749 action: || Action::ToggleTabBar,
750 contexts: &[Normal, FileExplorer, Terminal],
751 custom_contexts: &[],
752 },
753 CommandDef {
754 name_key: "cmd.toggle_status_bar",
755 desc_key: "cmd.toggle_status_bar_desc",
756 action: || Action::ToggleStatusBar,
757 contexts: &[Normal, FileExplorer, Terminal],
758 custom_contexts: &[],
759 },
760 CommandDef {
761 name_key: "cmd.toggle_prompt_line",
762 desc_key: "cmd.toggle_prompt_line_desc",
763 action: || Action::TogglePromptLine,
764 contexts: &[Normal, FileExplorer, Terminal],
765 custom_contexts: &[],
766 },
767 CommandDef {
768 name_key: "cmd.toggle_vertical_scrollbar",
769 desc_key: "cmd.toggle_vertical_scrollbar_desc",
770 action: || Action::ToggleVerticalScrollbar,
771 contexts: &[Normal, FileExplorer, Terminal],
772 custom_contexts: &[],
773 },
774 CommandDef {
775 name_key: "cmd.toggle_horizontal_scrollbar",
776 desc_key: "cmd.toggle_horizontal_scrollbar_desc",
777 action: || Action::ToggleHorizontalScrollbar,
778 contexts: &[Normal, FileExplorer, Terminal],
779 custom_contexts: &[],
780 },
781 CommandDef {
782 name_key: "cmd.focus_file_explorer",
783 desc_key: "cmd.focus_file_explorer_desc",
784 action: || Action::FocusFileExplorer,
785 contexts: &[Normal, Terminal],
786 custom_contexts: &[],
787 },
788 CommandDef {
789 name_key: "cmd.focus_editor",
790 desc_key: "cmd.focus_editor_desc",
791 action: || Action::FocusEditor,
792 contexts: &[FileExplorer],
793 custom_contexts: &[],
794 },
795 CommandDef {
796 name_key: "cmd.explorer_refresh",
797 desc_key: "cmd.explorer_refresh_desc",
798 action: || Action::FileExplorerRefresh,
799 contexts: &[FileExplorer],
800 custom_contexts: &[],
801 },
802 CommandDef {
803 name_key: "cmd.explorer_new_file",
804 desc_key: "cmd.explorer_new_file_desc",
805 action: || Action::FileExplorerNewFile,
806 contexts: &[FileExplorer],
807 custom_contexts: &[],
808 },
809 CommandDef {
810 name_key: "cmd.explorer_new_directory",
811 desc_key: "cmd.explorer_new_directory_desc",
812 action: || Action::FileExplorerNewDirectory,
813 contexts: &[FileExplorer],
814 custom_contexts: &[],
815 },
816 CommandDef {
817 name_key: "cmd.explorer_delete",
818 desc_key: "cmd.explorer_delete_desc",
819 action: || Action::FileExplorerDelete,
820 contexts: &[FileExplorer],
821 custom_contexts: &[],
822 },
823 CommandDef {
824 name_key: "cmd.explorer_rename",
825 desc_key: "cmd.explorer_rename_desc",
826 action: || Action::FileExplorerRename,
827 contexts: &[FileExplorer],
828 custom_contexts: &[],
829 },
830 CommandDef {
831 name_key: "cmd.toggle_hidden_files",
832 desc_key: "cmd.toggle_hidden_files_desc",
833 action: || Action::FileExplorerToggleHidden,
834 contexts: &[FileExplorer],
835 custom_contexts: &[],
836 },
837 CommandDef {
838 name_key: "cmd.toggle_gitignored_files",
839 desc_key: "cmd.toggle_gitignored_files_desc",
840 action: || Action::FileExplorerToggleGitignored,
841 contexts: &[FileExplorer],
842 custom_contexts: &[],
843 },
844 CommandDef {
846 name_key: "cmd.toggle_line_wrap",
847 desc_key: "cmd.toggle_line_wrap_desc",
848 action: || Action::ToggleLineWrap,
849 contexts: &[Normal],
850 custom_contexts: &[],
851 },
852 CommandDef {
853 name_key: "cmd.toggle_current_line_highlight",
854 desc_key: "cmd.toggle_current_line_highlight_desc",
855 action: || Action::ToggleCurrentLineHighlight,
856 contexts: &[Normal],
857 custom_contexts: &[],
858 },
859 CommandDef {
860 name_key: "cmd.toggle_page_view",
861 desc_key: "cmd.toggle_page_view_desc",
862 action: || Action::TogglePageView,
863 contexts: &[Normal],
864 custom_contexts: &[],
865 },
866 CommandDef {
867 name_key: "cmd.set_page_width",
868 desc_key: "cmd.set_page_width_desc",
869 action: || Action::SetPageWidth,
870 contexts: &[Normal],
871 custom_contexts: &[],
872 },
873 CommandDef {
874 name_key: "cmd.toggle_read_only",
875 desc_key: "cmd.toggle_read_only_desc",
876 action: || Action::ToggleReadOnly,
877 contexts: &[Normal],
878 custom_contexts: &[],
879 },
880 CommandDef {
881 name_key: "cmd.set_background",
882 desc_key: "cmd.set_background_desc",
883 action: || Action::SetBackground,
884 contexts: &[Normal],
885 custom_contexts: &[],
886 },
887 CommandDef {
888 name_key: "cmd.set_background_blend",
889 desc_key: "cmd.set_background_blend_desc",
890 action: || Action::SetBackgroundBlend,
891 contexts: &[Normal],
892 custom_contexts: &[],
893 },
894 CommandDef {
896 name_key: "cmd.search",
897 desc_key: "cmd.search_desc",
898 action: || Action::Search,
899 contexts: &[Normal],
900 custom_contexts: &[],
901 },
902 CommandDef {
903 name_key: "cmd.find_in_selection",
904 desc_key: "cmd.find_in_selection_desc",
905 action: || Action::FindInSelection,
906 contexts: &[Normal],
907 custom_contexts: &[],
908 },
909 CommandDef {
910 name_key: "cmd.find_next",
911 desc_key: "cmd.find_next_desc",
912 action: || Action::FindNext,
913 contexts: &[Normal],
914 custom_contexts: &[],
915 },
916 CommandDef {
917 name_key: "cmd.find_previous",
918 desc_key: "cmd.find_previous_desc",
919 action: || Action::FindPrevious,
920 contexts: &[Normal],
921 custom_contexts: &[],
922 },
923 CommandDef {
924 name_key: "cmd.find_selection_next",
925 desc_key: "cmd.find_selection_next_desc",
926 action: || Action::FindSelectionNext,
927 contexts: &[Normal],
928 custom_contexts: &[],
929 },
930 CommandDef {
931 name_key: "cmd.find_selection_previous",
932 desc_key: "cmd.find_selection_previous_desc",
933 action: || Action::FindSelectionPrevious,
934 contexts: &[Normal],
935 custom_contexts: &[],
936 },
937 CommandDef {
938 name_key: "cmd.replace",
939 desc_key: "cmd.replace_desc",
940 action: || Action::Replace,
941 contexts: &[Normal],
942 custom_contexts: &[],
943 },
944 CommandDef {
945 name_key: "cmd.query_replace",
946 desc_key: "cmd.query_replace_desc",
947 action: || Action::QueryReplace,
948 contexts: &[Normal],
949 custom_contexts: &[],
950 },
951 CommandDef {
953 name_key: "cmd.goto_line",
954 desc_key: "cmd.goto_line_desc",
955 action: || Action::GotoLine,
956 contexts: &[Normal],
957 custom_contexts: &[],
958 },
959 CommandDef {
960 name_key: "cmd.scan_line_index",
961 desc_key: "cmd.scan_line_index_desc",
962 action: || Action::ScanLineIndex,
963 contexts: &[Normal],
964 custom_contexts: &[],
965 },
966 CommandDef {
967 name_key: "cmd.smart_home",
968 desc_key: "cmd.smart_home_desc",
969 action: || Action::SmartHome,
970 contexts: &[Normal],
971 custom_contexts: &[],
972 },
973 CommandDef {
974 name_key: "cmd.show_completions",
975 desc_key: "cmd.show_completions_desc",
976 action: || Action::LspCompletion,
977 contexts: &[Normal],
978 custom_contexts: &[],
979 },
980 CommandDef {
981 name_key: "cmd.goto_definition",
982 desc_key: "cmd.goto_definition_desc",
983 action: || Action::LspGotoDefinition,
984 contexts: &[Normal],
985 custom_contexts: &[],
986 },
987 CommandDef {
988 name_key: "cmd.show_hover_info",
989 desc_key: "cmd.show_hover_info_desc",
990 action: || Action::LspHover,
991 contexts: &[Normal],
992 custom_contexts: &[],
993 },
994 CommandDef {
995 name_key: "cmd.find_references",
996 desc_key: "cmd.find_references_desc",
997 action: || Action::LspReferences,
998 contexts: &[Normal],
999 custom_contexts: &[],
1000 },
1001 CommandDef {
1002 name_key: "cmd.show_signature_help",
1003 desc_key: "cmd.show_signature_help_desc",
1004 action: || Action::LspSignatureHelp,
1005 contexts: &[Normal],
1006 custom_contexts: &[],
1007 },
1008 CommandDef {
1009 name_key: "cmd.code_actions",
1010 desc_key: "cmd.code_actions_desc",
1011 action: || Action::LspCodeActions,
1012 contexts: &[Normal],
1013 custom_contexts: &[],
1014 },
1015 CommandDef {
1016 name_key: "cmd.start_restart_lsp",
1017 desc_key: "cmd.start_restart_lsp_desc",
1018 action: || Action::LspRestart,
1019 contexts: &[Normal],
1020 custom_contexts: &[],
1021 },
1022 CommandDef {
1023 name_key: "cmd.stop_lsp",
1024 desc_key: "cmd.stop_lsp_desc",
1025 action: || Action::LspStop,
1026 contexts: &[Normal],
1027 custom_contexts: &[],
1028 },
1029 CommandDef {
1030 name_key: "cmd.toggle_lsp_for_buffer",
1031 desc_key: "cmd.toggle_lsp_for_buffer_desc",
1032 action: || Action::LspToggleForBuffer,
1033 contexts: &[Normal],
1034 custom_contexts: &[],
1035 },
1036 CommandDef {
1037 name_key: "cmd.toggle_mouse_hover",
1038 desc_key: "cmd.toggle_mouse_hover_desc",
1039 action: || Action::ToggleMouseHover,
1040 contexts: &[],
1041 custom_contexts: &[],
1042 },
1043 CommandDef {
1044 name_key: "cmd.navigate_back",
1045 desc_key: "cmd.navigate_back_desc",
1046 action: || Action::NavigateBack,
1047 contexts: &[Normal],
1048 custom_contexts: &[],
1049 },
1050 CommandDef {
1051 name_key: "cmd.navigate_forward",
1052 desc_key: "cmd.navigate_forward_desc",
1053 action: || Action::NavigateForward,
1054 contexts: &[Normal],
1055 custom_contexts: &[],
1056 },
1057 CommandDef {
1059 name_key: "cmd.toggle_comment",
1060 desc_key: "cmd.toggle_comment_desc",
1061 action: || Action::ToggleComment,
1062 contexts: &[Normal],
1063 custom_contexts: &[],
1064 },
1065 CommandDef {
1066 name_key: "cmd.dedent_selection",
1067 desc_key: "cmd.dedent_selection_desc",
1068 action: || Action::DedentSelection,
1069 contexts: &[Normal],
1070 custom_contexts: &[],
1071 },
1072 CommandDef {
1073 name_key: "cmd.goto_matching_bracket",
1074 desc_key: "cmd.goto_matching_bracket_desc",
1075 action: || Action::GoToMatchingBracket,
1076 contexts: &[Normal],
1077 custom_contexts: &[],
1078 },
1079 CommandDef {
1081 name_key: "cmd.jump_to_next_error",
1082 desc_key: "cmd.jump_to_next_error_desc",
1083 action: || Action::JumpToNextError,
1084 contexts: &[Normal],
1085 custom_contexts: &[],
1086 },
1087 CommandDef {
1088 name_key: "cmd.jump_to_previous_error",
1089 desc_key: "cmd.jump_to_previous_error_desc",
1090 action: || Action::JumpToPreviousError,
1091 contexts: &[Normal],
1092 custom_contexts: &[],
1093 },
1094 CommandDef {
1096 name_key: "cmd.rename_symbol",
1097 desc_key: "cmd.rename_symbol_desc",
1098 action: || Action::LspRename,
1099 contexts: &[Normal],
1100 custom_contexts: &[],
1101 },
1102 CommandDef {
1104 name_key: "cmd.list_bookmarks",
1105 desc_key: "cmd.list_bookmarks_desc",
1106 action: || Action::ListBookmarks,
1107 contexts: &[Normal],
1108 custom_contexts: &[],
1109 },
1110 CommandDef {
1111 name_key: "cmd.list_macros",
1112 desc_key: "cmd.list_macros_desc",
1113 action: || Action::ListMacros,
1114 contexts: &[Normal],
1115 custom_contexts: &[],
1116 },
1117 CommandDef {
1118 name_key: "cmd.record_macro",
1119 desc_key: "cmd.record_macro_desc",
1120 action: || Action::PromptRecordMacro,
1121 contexts: &[Normal],
1122 custom_contexts: &[],
1123 },
1124 CommandDef {
1125 name_key: "cmd.stop_recording_macro",
1126 desc_key: "cmd.stop_recording_macro_desc",
1127 action: || Action::StopMacroRecording,
1128 contexts: &[Normal],
1129 custom_contexts: &[],
1130 },
1131 CommandDef {
1132 name_key: "cmd.play_macro",
1133 desc_key: "cmd.play_macro_desc",
1134 action: || Action::PromptPlayMacro,
1135 contexts: &[Normal],
1136 custom_contexts: &[],
1137 },
1138 CommandDef {
1139 name_key: "cmd.play_last_macro",
1140 desc_key: "cmd.play_last_macro_desc",
1141 action: || Action::PlayLastMacro,
1142 contexts: &[Normal],
1143 custom_contexts: &[],
1144 },
1145 CommandDef {
1146 name_key: "cmd.set_bookmark",
1147 desc_key: "cmd.set_bookmark_desc",
1148 action: || Action::PromptSetBookmark,
1149 contexts: &[Normal],
1150 custom_contexts: &[],
1151 },
1152 CommandDef {
1153 name_key: "cmd.jump_to_bookmark",
1154 desc_key: "cmd.jump_to_bookmark_desc",
1155 action: || Action::PromptJumpToBookmark,
1156 contexts: &[Normal],
1157 custom_contexts: &[],
1158 },
1159 CommandDef {
1161 name_key: "cmd.show_manual",
1162 desc_key: "cmd.show_manual_desc",
1163 action: || Action::ShowHelp,
1164 contexts: &[],
1165 custom_contexts: &[],
1166 },
1167 CommandDef {
1168 name_key: "cmd.show_keyboard_shortcuts",
1169 desc_key: "cmd.show_keyboard_shortcuts_desc",
1170 action: || Action::ShowKeyboardShortcuts,
1171 contexts: &[],
1172 custom_contexts: &[],
1173 },
1174 CommandDef {
1175 name_key: "cmd.show_warnings",
1176 desc_key: "cmd.show_warnings_desc",
1177 action: || Action::ShowWarnings,
1178 contexts: &[],
1179 custom_contexts: &[],
1180 },
1181 CommandDef {
1182 name_key: "cmd.show_lsp_status",
1183 desc_key: "cmd.show_lsp_status_desc",
1184 action: || Action::ShowLspStatus,
1185 contexts: &[],
1186 custom_contexts: &[],
1187 },
1188 CommandDef {
1189 name_key: "cmd.show_remote_indicator_menu",
1190 desc_key: "cmd.show_remote_indicator_menu_desc",
1191 action: || Action::ShowRemoteIndicatorMenu,
1192 contexts: &[],
1193 custom_contexts: &[],
1194 },
1195 CommandDef {
1196 name_key: "cmd.clear_warnings",
1197 desc_key: "cmd.clear_warnings_desc",
1198 action: || Action::ClearWarnings,
1199 contexts: &[],
1200 custom_contexts: &[],
1201 },
1202 CommandDef {
1204 name_key: "cmd.dump_config",
1205 desc_key: "cmd.dump_config_desc",
1206 action: || Action::DumpConfig,
1207 contexts: &[],
1208 custom_contexts: &[],
1209 },
1210 CommandDef {
1211 name_key: "cmd.redraw_screen",
1212 desc_key: "cmd.redraw_screen_desc",
1213 action: || Action::RedrawScreen,
1214 contexts: &[],
1215 custom_contexts: &[],
1216 },
1217 CommandDef {
1218 name_key: "cmd.toggle_inlay_hints",
1219 desc_key: "cmd.toggle_inlay_hints_desc",
1220 action: || Action::ToggleInlayHints,
1221 contexts: &[Normal],
1222 custom_contexts: &[],
1223 },
1224 CommandDef {
1226 name_key: "cmd.select_theme",
1227 desc_key: "cmd.select_theme_desc",
1228 action: || Action::SelectTheme,
1229 contexts: &[],
1230 custom_contexts: &[],
1231 },
1232 CommandDef {
1234 name_key: "cmd.inspect_theme_at_cursor",
1235 desc_key: "cmd.inspect_theme_at_cursor_desc",
1236 action: || Action::InspectThemeAtCursor,
1237 contexts: &[Normal],
1238 custom_contexts: &[],
1239 },
1240 CommandDef {
1242 name_key: "cmd.select_keybinding_map",
1243 desc_key: "cmd.select_keybinding_map_desc",
1244 action: || Action::SelectKeybindingMap,
1245 contexts: &[],
1246 custom_contexts: &[],
1247 },
1248 CommandDef {
1250 name_key: "cmd.select_cursor_style",
1251 desc_key: "cmd.select_cursor_style_desc",
1252 action: || Action::SelectCursorStyle,
1253 contexts: &[],
1254 custom_contexts: &[],
1255 },
1256 CommandDef {
1258 name_key: "cmd.select_locale",
1259 desc_key: "cmd.select_locale_desc",
1260 action: || Action::SelectLocale,
1261 contexts: &[],
1262 custom_contexts: &[],
1263 },
1264 CommandDef {
1266 name_key: "cmd.open_settings",
1267 desc_key: "cmd.open_settings_desc",
1268 action: || Action::OpenSettings,
1269 contexts: &[],
1270 custom_contexts: &[],
1271 },
1272 CommandDef {
1274 name_key: "cmd.open_keybinding_editor",
1275 desc_key: "cmd.open_keybinding_editor_desc",
1276 action: || Action::OpenKeybindingEditor,
1277 contexts: &[],
1278 custom_contexts: &[],
1279 },
1280 CommandDef {
1282 name_key: "cmd.calibrate_input",
1283 desc_key: "cmd.calibrate_input_desc",
1284 action: || Action::CalibrateInput,
1285 contexts: &[],
1286 custom_contexts: &[],
1287 },
1288 CommandDef {
1290 name_key: "cmd.open_terminal",
1291 desc_key: "cmd.open_terminal_desc",
1292 action: || Action::OpenTerminal,
1293 contexts: &[],
1294 custom_contexts: &[],
1295 },
1296 CommandDef {
1297 name_key: "cmd.focus_terminal",
1298 desc_key: "cmd.focus_terminal_desc",
1299 action: || Action::FocusTerminal,
1300 contexts: &[Normal],
1301 custom_contexts: &[],
1302 },
1303 CommandDef {
1304 name_key: "cmd.exit_terminal_mode",
1305 desc_key: "cmd.exit_terminal_mode_desc",
1306 action: || Action::TerminalEscape,
1307 contexts: &[Terminal],
1308 custom_contexts: &[],
1309 },
1310 CommandDef {
1311 name_key: "cmd.toggle_keyboard_capture",
1312 desc_key: "cmd.toggle_keyboard_capture_desc",
1313 action: || Action::ToggleKeyboardCapture,
1314 contexts: &[Terminal],
1315 custom_contexts: &[],
1316 },
1317 CommandDef {
1319 name_key: "cmd.shell_command",
1320 desc_key: "cmd.shell_command_desc",
1321 action: || Action::ShellCommand,
1322 contexts: &[Normal],
1323 custom_contexts: &[],
1324 },
1325 CommandDef {
1326 name_key: "cmd.shell_command_replace",
1327 desc_key: "cmd.shell_command_replace_desc",
1328 action: || Action::ShellCommandReplace,
1329 contexts: &[Normal],
1330 custom_contexts: &[],
1331 },
1332 CommandDef {
1334 name_key: "cmd.event_debug",
1335 desc_key: "cmd.event_debug_desc",
1336 action: || Action::EventDebug,
1337 contexts: &[],
1338 custom_contexts: &[],
1339 },
1340 CommandDef {
1342 name_key: "cmd.suspend_process",
1343 desc_key: "cmd.suspend_process_desc",
1344 action: || Action::SuspendProcess,
1345 contexts: &[Normal, FileExplorer, Terminal],
1346 custom_contexts: &[],
1347 },
1348 CommandDef {
1350 name_key: "cmd.load_plugin_from_buffer",
1351 desc_key: "cmd.load_plugin_from_buffer_desc",
1352 action: || Action::LoadPluginFromBuffer,
1353 contexts: &[Normal],
1354 custom_contexts: &[],
1355 },
1356 CommandDef {
1358 name_key: "cmd.init_reload",
1359 desc_key: "cmd.init_reload_desc",
1360 action: || Action::InitReload,
1361 contexts: &[Normal],
1362 custom_contexts: &[],
1363 },
1364 CommandDef {
1365 name_key: "cmd.init_edit",
1366 desc_key: "cmd.init_edit_desc",
1367 action: || Action::InitEdit,
1368 contexts: &[Normal],
1369 custom_contexts: &[],
1370 },
1371 CommandDef {
1372 name_key: "cmd.init_check",
1373 desc_key: "cmd.init_check_desc",
1374 action: || Action::InitCheck,
1375 contexts: &[Normal],
1376 custom_contexts: &[],
1377 },
1378 CommandDef {
1383 name_key: "cmd.resume_live_grep",
1384 desc_key: "cmd.resume_live_grep_desc",
1385 action: || Action::ResumeLiveGrep,
1386 contexts: &[Normal],
1387 custom_contexts: &[],
1388 },
1389 CommandDef {
1390 name_key: "cmd.toggle_utility_dock",
1391 desc_key: "cmd.toggle_utility_dock_desc",
1392 action: || Action::ToggleUtilityDock,
1393 contexts: &[Normal],
1394 custom_contexts: &[],
1395 },
1396 CommandDef {
1397 name_key: "cmd.open_terminal_in_dock",
1398 desc_key: "cmd.open_terminal_in_dock_desc",
1399 action: || Action::OpenTerminalInDock,
1400 contexts: &[Normal],
1401 custom_contexts: &[],
1402 },
1403 CommandDef {
1406 name_key: "cmd.workspace_trust",
1407 desc_key: "cmd.workspace_trust_desc",
1408 action: || Action::WorkspaceTrustPrompt,
1409 contexts: &[],
1410 custom_contexts: &[],
1411 },
1412];
1413
1414pub fn get_all_commands() -> Vec<Command> {
1416 COMMAND_DEFS
1417 .iter()
1418 .map(|def| Command {
1419 name: t!(def.name_key).to_string(),
1420 description: t!(def.desc_key).to_string(),
1421 action: (def.action)(),
1422 contexts: def.contexts.to_vec(),
1423 custom_contexts: def.custom_contexts.iter().map(|s| s.to_string()).collect(),
1424 source: CommandSource::Builtin,
1425 terminal_bypass: false,
1429 })
1430 .collect()
1431}
1432
1433pub fn filter_commands(
1435 query: &str,
1436 current_context: KeyContext,
1437 keybinding_resolver: &crate::input::keybindings::KeybindingResolver,
1438) -> Vec<Suggestion> {
1439 let query_lower = query.to_lowercase();
1440 let commands = get_all_commands();
1441
1442 let is_available = |cmd: &Command| -> bool {
1444 cmd.contexts.is_empty() || cmd.contexts.contains(¤t_context)
1446 };
1447
1448 let matches_query = |cmd: &Command| -> bool {
1450 if query.is_empty() {
1451 return true;
1452 }
1453
1454 let name_lower = cmd.name.to_lowercase();
1455 let mut query_chars = query_lower.chars();
1456 let mut current_char = query_chars.next();
1457
1458 for name_char in name_lower.chars() {
1459 if let Some(qc) = current_char {
1460 if qc == name_char {
1461 current_char = query_chars.next();
1462 }
1463 } else {
1464 break;
1465 }
1466 }
1467
1468 current_char.is_none() };
1470
1471 let current_context_ref = ¤t_context;
1473 let mut suggestions: Vec<Suggestion> = commands
1474 .into_iter()
1475 .filter(|cmd| matches_query(cmd))
1476 .map(|cmd| {
1477 let available = is_available(&cmd);
1478 let keybinding = keybinding_resolver
1479 .get_keybinding_for_action(&cmd.action, current_context_ref.clone());
1480 Suggestion::new(cmd.name.clone())
1481 .with_description(cmd.description)
1482 .set_disabled(!available)
1483 .with_keybinding(keybinding)
1484 })
1485 .collect();
1486
1487 suggestions.sort_by_key(|s| s.disabled);
1489
1490 suggestions
1491}