1use crate::app::AppMode;
4
5#[derive(Debug, Clone)]
7pub struct ModeIndicator {
8 pub mode: AppMode,
10 pub show_shortcut: bool,
12 pub show_capabilities: bool,
14}
15
16impl ModeIndicator {
17 pub fn new(mode: AppMode) -> Self {
19 Self {
20 mode,
21 show_shortcut: true,
22 show_capabilities: false,
23 }
24 }
25
26 pub fn display_text(&self) -> String {
28 if self.show_shortcut {
29 format!("[{}] {}", self.mode.shortcut(), self.mode.display_name())
30 } else {
31 format!("[{}]", self.mode.display_name())
32 }
33 }
34
35 pub fn short_text(&self) -> &'static str {
37 self.mode.display_name()
38 }
39
40 pub fn get_capabilities(&self) -> Vec<&'static str> {
42 match self.mode {
43 AppMode::Chat => vec!["QuestionAnswering", "FreeformChat"],
44 AppMode::Command => vec!["CodeGeneration", "FileOperations", "CommandExecution"],
45 AppMode::Diff => vec!["CodeModification", "FileOperations"],
46 AppMode::Help => vec!["QuestionAnswering"],
47 }
48 }
49
50 pub fn capabilities_text(&self) -> String {
52 let caps = self.get_capabilities();
53 format!("Capabilities: {}", caps.join(", "))
54 }
55
56 pub fn set_mode(&mut self, mode: AppMode) {
58 self.mode = mode;
59 }
60
61 pub fn toggle_shortcut_display(&mut self) {
63 self.show_shortcut = !self.show_shortcut;
64 }
65
66 pub fn toggle_capabilities_display(&mut self) {
68 self.show_capabilities = !self.show_capabilities;
69 }
70
71 pub fn show_capabilities_enabled(&mut self) {
73 self.show_capabilities = true;
74 }
75
76 pub fn hide_capabilities_enabled(&mut self) {
78 self.show_capabilities = false;
79 }
80}
81
82impl Default for ModeIndicator {
83 fn default() -> Self {
84 Self::new(AppMode::Chat)
85 }
86}
87
88#[derive(Debug, Clone)]
90pub struct ModeSelectionMenu {
91 pub modes: Vec<AppMode>,
93 pub selected: usize,
95 pub open: bool,
97 pub show_confirmation: bool,
99 pub previous_mode: AppMode,
101}
102
103impl ModeSelectionMenu {
104 pub fn new() -> Self {
106 Self {
107 modes: vec![
108 AppMode::Chat,
109 AppMode::Command,
110 AppMode::Diff,
111 AppMode::Help,
112 ],
113 selected: 0,
114 open: false,
115 show_confirmation: false,
116 previous_mode: AppMode::Chat,
117 }
118 }
119
120 pub fn open(&mut self, current_mode: AppMode) {
122 self.open = true;
123 self.previous_mode = current_mode;
124 if let Some(pos) = self.modes.iter().position(|&m| m == current_mode) {
126 self.selected = pos;
127 }
128 }
129
130 pub fn close(&mut self) {
132 self.open = false;
133 self.show_confirmation = false;
134 }
135
136 pub fn selected_mode(&self) -> AppMode {
138 self.modes
139 .get(self.selected)
140 .copied()
141 .unwrap_or(AppMode::Chat)
142 }
143
144 pub fn select_next(&mut self) {
146 if self.selected < self.modes.len().saturating_sub(1) {
147 self.selected += 1;
148 } else {
149 self.selected = 0;
150 }
151 }
152
153 pub fn select_prev(&mut self) {
155 if self.selected > 0 {
156 self.selected -= 1;
157 } else {
158 self.selected = self.modes.len().saturating_sub(1);
159 }
160 }
161
162 pub fn confirm_switch(&mut self) -> AppMode {
164 let mode = self.selected_mode();
165 self.close();
166 mode
167 }
168
169 pub fn cancel_switch(&mut self) {
171 self.close();
172 }
173
174 pub fn get_mode_descriptions(&self) -> Vec<(&AppMode, &'static str)> {
176 self.modes
177 .iter()
178 .map(|mode| {
179 let desc = match mode {
180 AppMode::Chat => "Chat with the AI assistant",
181 AppMode::Command => "Execute commands and generate code",
182 AppMode::Diff => "Review and apply code changes",
183 AppMode::Help => "Get help and documentation",
184 };
185 (mode, desc)
186 })
187 .collect()
188 }
189
190 pub fn get_shortcuts(&self) -> Vec<(&'static str, &'static str)> {
192 vec![
193 ("Ctrl+1", "Chat Mode"),
194 ("Ctrl+2", "Command Mode"),
195 ("Ctrl+3", "Diff Mode"),
196 ("Ctrl+4", "Help Mode"),
197 ]
198 }
199}
200
201impl Default for ModeSelectionMenu {
202 fn default() -> Self {
203 Self::new()
204 }
205}
206
207#[derive(Debug, Clone)]
209pub struct MenuItem {
210 pub label: String,
212 pub description: Option<String>,
214}
215
216impl MenuItem {
217 pub fn new(label: impl Into<String>) -> Self {
219 Self {
220 label: label.into(),
221 description: None,
222 }
223 }
224
225 pub fn with_description(mut self, desc: impl Into<String>) -> Self {
227 self.description = Some(desc.into());
228 self
229 }
230}
231
232pub struct MenuWidget {
234 pub items: Vec<MenuItem>,
236 pub selected: usize,
238 pub open: bool,
240 pub title: Option<String>,
242 pub scroll: usize,
244}
245
246impl MenuWidget {
247 pub fn new() -> Self {
249 Self {
250 items: Vec::new(),
251 selected: 0,
252 open: false,
253 title: None,
254 scroll: 0,
255 }
256 }
257
258 pub fn with_title(title: impl Into<String>) -> Self {
260 Self {
261 items: Vec::new(),
262 selected: 0,
263 open: false,
264 title: Some(title.into()),
265 scroll: 0,
266 }
267 }
268
269 pub fn add_item(&mut self, item: MenuItem) {
271 self.items.push(item);
272 }
273
274 pub fn add_items(&mut self, items: Vec<MenuItem>) {
276 self.items.extend(items);
277 }
278
279 pub fn select_next(&mut self) {
281 if self.selected < self.items.len().saturating_sub(1) {
282 self.selected += 1;
283 self.ensure_visible(10); }
285 }
286
287 pub fn select_prev(&mut self) {
289 if self.selected > 0 {
290 self.selected -= 1;
291 self.ensure_visible(10);
292 }
293 }
294
295 pub fn select_first(&mut self) {
297 self.selected = 0;
298 self.scroll = 0;
299 }
300
301 pub fn select_last(&mut self) {
303 self.selected = self.items.len().saturating_sub(1);
304 self.ensure_visible(10);
305 }
306
307 fn ensure_visible(&mut self, visible_height: usize) {
309 if self.selected < self.scroll {
310 self.scroll = self.selected;
311 } else if self.selected >= self.scroll + visible_height {
312 self.scroll = self.selected.saturating_sub(visible_height - 1);
313 }
314 }
315
316 pub fn selected_item(&self) -> Option<&MenuItem> {
318 self.items.get(self.selected)
319 }
320
321 pub fn selected_index(&self) -> usize {
323 self.selected
324 }
325
326 pub fn open(&mut self) {
328 self.open = true;
329 }
330
331 pub fn close(&mut self) {
333 self.open = false;
334 }
335
336 pub fn toggle(&mut self) {
338 self.open = !self.open;
339 }
340
341 pub fn visible_items(&self, height: usize) -> Vec<(usize, &MenuItem)> {
343 self.items
344 .iter()
345 .enumerate()
346 .skip(self.scroll)
347 .take(height)
348 .collect()
349 }
350
351 pub fn clear(&mut self) {
353 self.items.clear();
354 self.selected = 0;
355 self.scroll = 0;
356 }
357
358 pub fn item_count(&self) -> usize {
360 self.items.len()
361 }
362
363 pub fn is_empty(&self) -> bool {
365 self.items.is_empty()
366 }
367}
368
369impl Default for MenuWidget {
370 fn default() -> Self {
371 Self::new()
372 }
373}
374
375pub struct ListWidget {
377 pub items: Vec<String>,
379 pub selected: Option<usize>,
381 pub filter: String,
383 pub multi_select: bool,
385 pub selected_items: std::collections::HashSet<usize>,
387 pub scroll: usize,
389}
390
391impl ListWidget {
392 pub fn new() -> Self {
394 Self {
395 items: Vec::new(),
396 selected: None,
397 filter: String::new(),
398 multi_select: false,
399 selected_items: std::collections::HashSet::new(),
400 scroll: 0,
401 }
402 }
403
404 pub fn with_multi_select(mut self) -> Self {
406 self.multi_select = true;
407 self
408 }
409
410 pub fn add_item(&mut self, item: impl Into<String>) {
412 self.items.push(item.into());
413 }
414
415 pub fn add_items(&mut self, items: Vec<String>) {
417 self.items.extend(items);
418 }
419
420 pub fn set_filter(&mut self, filter: impl Into<String>) {
422 self.filter = filter.into();
423 self.scroll = 0; }
425
426 pub fn clear_filter(&mut self) {
428 self.filter.clear();
429 self.scroll = 0;
430 }
431
432 pub fn filtered_items(&self) -> Vec<(usize, &String)> {
434 self.items
435 .iter()
436 .enumerate()
437 .filter(|(_, item)| item.to_lowercase().contains(&self.filter.to_lowercase()))
438 .collect()
439 }
440
441 pub fn visible_items(&self, height: usize) -> Vec<(usize, &String)> {
443 self.filtered_items()
444 .into_iter()
445 .skip(self.scroll)
446 .take(height)
447 .collect()
448 }
449
450 pub fn select_next(&mut self) {
452 let filtered = self.filtered_items();
453 if filtered.is_empty() {
454 return;
455 }
456
457 match self.selected {
458 None => {
459 self.selected = Some(filtered[0].0);
460 self.scroll = 0;
461 }
462 Some(idx) => {
463 if let Some(pos) = filtered.iter().position(|(i, _)| *i == idx) {
464 if pos < filtered.len() - 1 {
465 self.selected = Some(filtered[pos + 1].0);
466 }
467 }
468 }
469 }
470 }
471
472 pub fn select_prev(&mut self) {
474 let filtered = self.filtered_items();
475 if filtered.is_empty() {
476 return;
477 }
478
479 match self.selected {
480 None => {}
481 Some(idx) => {
482 if let Some(pos) = filtered.iter().position(|(i, _)| *i == idx) {
483 if pos > 0 {
484 self.selected = Some(filtered[pos - 1].0);
485 }
486 }
487 }
488 }
489 }
490
491 pub fn toggle_selection(&mut self) {
493 if self.multi_select {
494 if let Some(idx) = self.selected {
495 if self.selected_items.contains(&idx) {
496 self.selected_items.remove(&idx);
497 } else {
498 self.selected_items.insert(idx);
499 }
500 }
501 }
502 }
503
504 pub fn select_all(&mut self) {
506 if self.multi_select {
507 let indices: Vec<usize> = self
508 .filtered_items()
509 .into_iter()
510 .map(|(idx, _)| idx)
511 .collect();
512 for idx in indices {
513 self.selected_items.insert(idx);
514 }
515 }
516 }
517
518 pub fn deselect_all(&mut self) {
520 self.selected_items.clear();
521 }
522
523 pub fn selected_item(&self) -> Option<&String> {
525 self.selected.and_then(|idx| self.items.get(idx))
526 }
527
528 pub fn get_selected_items(&self) -> Vec<&String> {
530 self.selected_items
531 .iter()
532 .filter_map(|idx| self.items.get(*idx))
533 .collect()
534 }
535
536 pub fn clear(&mut self) {
538 self.items.clear();
539 self.selected = None;
540 self.selected_items.clear();
541 self.scroll = 0;
542 }
543
544 pub fn item_count(&self) -> usize {
546 self.items.len()
547 }
548
549 pub fn is_empty(&self) -> bool {
551 self.items.is_empty()
552 }
553}
554
555impl Default for ListWidget {
556 fn default() -> Self {
557 Self::new()
558 }
559}
560
561#[derive(Debug, Clone, Copy, PartialEq, Eq)]
563pub enum DialogType {
564 Input,
566 Confirm,
568 Message,
570}
571
572#[derive(Debug, Clone, Copy, PartialEq, Eq)]
574pub enum DialogResult {
575 Confirmed,
577 Cancelled,
579 Pending,
581}
582
583pub struct DialogWidget {
585 pub dialog_type: DialogType,
587 pub title: String,
589 pub message: String,
591 pub input: String,
593 pub cursor: usize,
595 pub result: DialogResult,
597 pub validator: Option<fn(&str) -> bool>,
599 pub error_message: Option<String>,
601 pub confirmed: Option<bool>,
603}
604
605impl DialogWidget {
606 pub fn new(
608 dialog_type: DialogType,
609 title: impl Into<String>,
610 message: impl Into<String>,
611 ) -> Self {
612 Self {
613 dialog_type,
614 title: title.into(),
615 message: message.into(),
616 input: String::new(),
617 cursor: 0,
618 result: DialogResult::Pending,
619 validator: None,
620 error_message: None,
621 confirmed: None,
622 }
623 }
624
625 pub fn with_validator(mut self, validator: fn(&str) -> bool) -> Self {
627 self.validator = Some(validator);
628 self
629 }
630
631 pub fn insert_char(&mut self, ch: char) {
633 if ch.is_ascii_graphic() || ch == ' ' {
634 self.input.insert(self.cursor, ch);
635 self.cursor += 1;
636 self.error_message = None;
637 }
638 }
639
640 pub fn backspace(&mut self) {
642 if self.cursor > 0 {
643 self.input.remove(self.cursor - 1);
644 self.cursor -= 1;
645 self.error_message = None;
646 }
647 }
648
649 pub fn delete(&mut self) {
651 if self.cursor < self.input.len() {
652 self.input.remove(self.cursor);
653 }
654 }
655
656 pub fn cursor_left(&mut self) {
658 if self.cursor > 0 {
659 self.cursor -= 1;
660 }
661 }
662
663 pub fn cursor_right(&mut self) {
665 if self.cursor < self.input.len() {
666 self.cursor += 1;
667 }
668 }
669
670 pub fn cursor_start(&mut self) {
672 self.cursor = 0;
673 }
674
675 pub fn cursor_end(&mut self) {
677 self.cursor = self.input.len();
678 }
679
680 pub fn get_input(&self) -> String {
682 self.input.clone()
683 }
684
685 pub fn validate(&mut self) -> bool {
687 if let Some(validator) = self.validator {
688 if validator(&self.input) {
689 self.error_message = None;
690 true
691 } else {
692 self.error_message = Some("Invalid input".to_string());
693 false
694 }
695 } else {
696 true
697 }
698 }
699
700 pub fn confirm(&mut self) {
702 match self.dialog_type {
703 DialogType::Input => {
704 if self.validate() {
705 self.result = DialogResult::Confirmed;
706 }
707 }
708 DialogType::Confirm => {
709 self.confirmed = Some(true);
710 self.result = DialogResult::Confirmed;
711 }
712 DialogType::Message => {
713 self.result = DialogResult::Confirmed;
714 }
715 }
716 }
717
718 pub fn cancel(&mut self) {
720 if self.dialog_type == DialogType::Confirm {
721 self.confirmed = Some(false);
722 }
723 self.result = DialogResult::Cancelled;
724 }
725
726 pub fn is_confirmed(&self) -> bool {
728 self.result == DialogResult::Confirmed
729 }
730
731 pub fn is_cancelled(&self) -> bool {
733 self.result == DialogResult::Cancelled
734 }
735
736 pub fn is_pending(&self) -> bool {
738 self.result == DialogResult::Pending
739 }
740
741 pub fn clear_input(&mut self) {
743 self.input.clear();
744 self.cursor = 0;
745 self.error_message = None;
746 }
747}
748
749#[derive(Debug, Clone, Copy, PartialEq, Eq)]
751pub enum SplitDirection {
752 Vertical,
754 Horizontal,
756}
757
758pub struct SplitViewWidget {
760 pub left_content: String,
762 pub right_content: String,
764 pub split_ratio: u8,
766 pub direction: SplitDirection,
768 pub active_panel: usize,
770 pub left_scroll: usize,
772 pub right_scroll: usize,
774}
775
776impl SplitViewWidget {
777 pub fn new() -> Self {
779 Self {
780 left_content: String::new(),
781 right_content: String::new(),
782 split_ratio: 50,
783 direction: SplitDirection::Vertical,
784 active_panel: 0,
785 left_scroll: 0,
786 right_scroll: 0,
787 }
788 }
789
790 pub fn horizontal() -> Self {
792 Self {
793 left_content: String::new(),
794 right_content: String::new(),
795 split_ratio: 50,
796 direction: SplitDirection::Horizontal,
797 active_panel: 0,
798 left_scroll: 0,
799 right_scroll: 0,
800 }
801 }
802
803 pub fn set_left(&mut self, content: impl Into<String>) {
805 self.left_content = content.into();
806 }
807
808 pub fn set_right(&mut self, content: impl Into<String>) {
810 self.right_content = content.into();
811 }
812
813 pub fn adjust_split(&mut self, delta: i8) {
815 let new_ratio = (self.split_ratio as i16 + delta as i16).clamp(20, 80) as u8;
816 self.split_ratio = new_ratio;
817 }
818
819 pub fn switch_panel(&mut self) {
821 self.active_panel = 1 - self.active_panel;
822 }
823
824 pub fn active_content(&self) -> &str {
826 if self.active_panel == 0 {
827 &self.left_content
828 } else {
829 &self.right_content
830 }
831 }
832
833 pub fn active_scroll(&self) -> usize {
835 if self.active_panel == 0 {
836 self.left_scroll
837 } else {
838 self.right_scroll
839 }
840 }
841
842 pub fn scroll_up(&mut self) {
844 if self.active_panel == 0 {
845 if self.left_scroll > 0 {
846 self.left_scroll -= 1;
847 }
848 } else if self.right_scroll > 0 {
849 self.right_scroll -= 1;
850 }
851 }
852
853 pub fn scroll_down(&mut self) {
855 if self.active_panel == 0 {
856 self.left_scroll += 1;
857 } else {
858 self.right_scroll += 1;
859 }
860 }
861}
862
863impl Default for SplitViewWidget {
864 fn default() -> Self {
865 Self::new()
866 }
867}
868
869pub struct TabWidget {
871 pub tabs: Vec<String>,
873 pub active: usize,
875 pub content: Vec<String>,
877 pub scroll: usize,
879}
880
881impl TabWidget {
882 pub fn new() -> Self {
884 Self {
885 tabs: Vec::new(),
886 active: 0,
887 content: Vec::new(),
888 scroll: 0,
889 }
890 }
891
892 pub fn add_tab(&mut self, title: impl Into<String>) {
894 self.tabs.push(title.into());
895 self.content.push(String::new());
896 }
897
898 pub fn add_tab_with_content(&mut self, title: impl Into<String>, content: impl Into<String>) {
900 self.tabs.push(title.into());
901 self.content.push(content.into());
902 }
903
904 pub fn select_next(&mut self) {
906 if self.active < self.tabs.len().saturating_sub(1) {
907 self.active += 1;
908 self.ensure_visible(10);
909 }
910 }
911
912 pub fn select_prev(&mut self) {
914 if self.active > 0 {
915 self.active -= 1;
916 self.ensure_visible(10);
917 }
918 }
919
920 pub fn select_tab(&mut self, index: usize) {
922 if index < self.tabs.len() {
923 self.active = index;
924 self.ensure_visible(10);
925 }
926 }
927
928 fn ensure_visible(&mut self, visible_width: usize) {
930 if self.active < self.scroll {
931 self.scroll = self.active;
932 } else if self.active >= self.scroll + visible_width {
933 self.scroll = self.active.saturating_sub(visible_width - 1);
934 }
935 }
936
937 pub fn active_tab(&self) -> Option<&String> {
939 self.tabs.get(self.active)
940 }
941
942 pub fn active_content(&self) -> Option<&String> {
944 self.content.get(self.active)
945 }
946
947 pub fn set_active_content(&mut self, content: impl Into<String>) {
949 if let Some(c) = self.content.get_mut(self.active) {
950 *c = content.into();
951 }
952 }
953
954 pub fn visible_tabs(&self, width: usize) -> Vec<(usize, &String)> {
956 self.tabs
957 .iter()
958 .enumerate()
959 .skip(self.scroll)
960 .take(width)
961 .collect()
962 }
963
964 pub fn close_tab(&mut self, index: usize) {
966 if index < self.tabs.len() {
967 self.tabs.remove(index);
968 self.content.remove(index);
969
970 if self.active >= self.tabs.len() && self.active > 0 {
971 self.active -= 1;
972 }
973 }
974 }
975
976 pub fn close_active_tab(&mut self) {
978 self.close_tab(self.active);
979 }
980
981 pub fn tab_count(&self) -> usize {
983 self.tabs.len()
984 }
985
986 pub fn is_empty(&self) -> bool {
988 self.tabs.is_empty()
989 }
990
991 pub fn clear(&mut self) {
993 self.tabs.clear();
994 self.content.clear();
995 self.active = 0;
996 self.scroll = 0;
997 }
998}
999
1000impl Default for TabWidget {
1001 fn default() -> Self {
1002 Self::new()
1003 }
1004}
1005
1006#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1008pub enum VimMode {
1009 Normal,
1011 Insert,
1013 Visual,
1015 Command,
1017}
1018
1019pub struct VimKeybindings {
1021 pub enabled: bool,
1023 pub mode: VimMode,
1025 pub command_buffer: String,
1027}
1028
1029impl VimKeybindings {
1030 pub fn new() -> Self {
1032 Self {
1033 enabled: false,
1034 mode: VimMode::Normal,
1035 command_buffer: String::new(),
1036 }
1037 }
1038
1039 pub fn enable(&mut self) {
1041 self.enabled = true;
1042 self.mode = VimMode::Normal;
1043 }
1044
1045 pub fn disable(&mut self) {
1047 self.enabled = false;
1048 self.mode = VimMode::Normal;
1049 self.command_buffer.clear();
1050 }
1051
1052 pub fn toggle(&mut self) {
1054 if self.enabled {
1055 self.disable();
1056 } else {
1057 self.enable();
1058 }
1059 }
1060
1061 pub fn enter_insert(&mut self) {
1063 if self.enabled {
1064 self.mode = VimMode::Insert;
1065 }
1066 }
1067
1068 pub fn enter_normal(&mut self) {
1070 if self.enabled {
1071 self.mode = VimMode::Normal;
1072 self.command_buffer.clear();
1073 }
1074 }
1075
1076 pub fn enter_visual(&mut self) {
1078 if self.enabled {
1079 self.mode = VimMode::Visual;
1080 }
1081 }
1082
1083 pub fn enter_command(&mut self) {
1085 if self.enabled {
1086 self.mode = VimMode::Command;
1087 self.command_buffer.clear();
1088 }
1089 }
1090
1091 pub fn add_to_command(&mut self, ch: char) {
1093 self.command_buffer.push(ch);
1094 }
1095
1096 pub fn clear_command(&mut self) {
1098 self.command_buffer.clear();
1099 }
1100
1101 pub fn get_command(&self) -> &str {
1103 &self.command_buffer
1104 }
1105
1106 pub fn is_normal(&self) -> bool {
1108 self.enabled && self.mode == VimMode::Normal
1109 }
1110
1111 pub fn is_insert(&self) -> bool {
1113 self.enabled && self.mode == VimMode::Insert
1114 }
1115
1116 pub fn is_visual(&self) -> bool {
1118 self.enabled && self.mode == VimMode::Visual
1119 }
1120
1121 pub fn is_command(&self) -> bool {
1123 self.enabled && self.mode == VimMode::Command
1124 }
1125}
1126
1127impl Default for VimKeybindings {
1128 fn default() -> Self {
1129 Self::new()
1130 }
1131}
1132
1133#[cfg(test)]
1134mod tests {
1135 use super::*;
1136
1137 #[test]
1138 fn test_menu_widget() {
1139 let mut menu = MenuWidget::new();
1140 menu.add_item(MenuItem::new("Option 1"));
1141 menu.add_item(MenuItem::new("Option 2"));
1142
1143 assert_eq!(menu.selected, 0);
1144 menu.select_next();
1145 assert_eq!(menu.selected, 1);
1146 menu.select_prev();
1147 assert_eq!(menu.selected, 0);
1148 }
1149
1150 #[test]
1151 fn test_menu_widget_with_title() {
1152 let menu = MenuWidget::with_title("Main Menu");
1153 assert_eq!(menu.title, Some("Main Menu".to_string()));
1154 assert!(!menu.open);
1155 }
1156
1157 #[test]
1158 fn test_menu_widget_open_close() {
1159 let mut menu = MenuWidget::new();
1160 assert!(!menu.open);
1161
1162 menu.open();
1163 assert!(menu.open);
1164
1165 menu.close();
1166 assert!(!menu.open);
1167
1168 menu.toggle();
1169 assert!(menu.open);
1170 }
1171
1172 #[test]
1173 fn test_menu_widget_first_last() {
1174 let mut menu = MenuWidget::new();
1175 menu.add_item(MenuItem::new("Item 1"));
1176 menu.add_item(MenuItem::new("Item 2"));
1177 menu.add_item(MenuItem::new("Item 3"));
1178 menu.add_item(MenuItem::new("Item 4"));
1179
1180 menu.select_last();
1181 assert_eq!(menu.selected, 3);
1182
1183 menu.select_first();
1184 assert_eq!(menu.selected, 0);
1185 }
1186
1187 #[test]
1188 fn test_menu_widget_visible_items() {
1189 let mut menu = MenuWidget::new();
1190 for i in 0..10 {
1191 menu.add_item(MenuItem::new(format!("Item {}", i)));
1192 }
1193
1194 let visible = menu.visible_items(5);
1195 assert_eq!(visible.len(), 5);
1196
1197 menu.scroll = 3;
1198 let visible = menu.visible_items(5);
1199 assert_eq!(visible.len(), 5);
1200 assert_eq!(visible[0].0, 3);
1201 }
1202
1203 #[test]
1204 fn test_menu_widget_clear() {
1205 let mut menu = MenuWidget::new();
1206 menu.add_item(MenuItem::new("Item 1"));
1207 menu.add_item(MenuItem::new("Item 2"));
1208 menu.selected = 1;
1209
1210 menu.clear();
1211 assert!(menu.items.is_empty());
1212 assert_eq!(menu.selected, 0);
1213 assert_eq!(menu.scroll, 0);
1214 }
1215
1216 #[test]
1217 fn test_menu_widget_add_items() {
1218 let mut menu = MenuWidget::new();
1219 let items = vec![
1220 MenuItem::new("Item 1"),
1221 MenuItem::new("Item 2"),
1222 MenuItem::new("Item 3"),
1223 ];
1224 menu.add_items(items);
1225
1226 assert_eq!(menu.item_count(), 3);
1227 }
1228
1229 #[test]
1230 fn test_menu_widget_is_empty() {
1231 let menu = MenuWidget::new();
1232 assert!(menu.is_empty());
1233
1234 let mut menu = MenuWidget::new();
1235 menu.add_item(MenuItem::new("Item"));
1236 assert!(!menu.is_empty());
1237 }
1238
1239 #[test]
1240 fn test_list_widget() {
1241 let mut list = ListWidget::new();
1242 list.add_item("apple");
1243 list.add_item("banana");
1244 list.add_item("cherry");
1245
1246 assert_eq!(list.filtered_items().len(), 3);
1247
1248 list.set_filter("app");
1249 assert_eq!(list.filtered_items().len(), 1);
1250 }
1251
1252 #[test]
1253 fn test_list_widget_selection() {
1254 let mut list = ListWidget::new();
1255 list.add_item("item1");
1256 list.add_item("item2");
1257 list.add_item("item3");
1258
1259 list.select_next();
1260 assert_eq!(list.selected, Some(0));
1261
1262 list.select_next();
1263 assert_eq!(list.selected, Some(1));
1264 }
1265
1266 #[test]
1267 fn test_list_widget_multi_select() {
1268 let mut list = ListWidget::new().with_multi_select();
1269 list.add_item("item1");
1270 list.add_item("item2");
1271 list.add_item("item3");
1272
1273 assert!(list.multi_select);
1274
1275 list.select_next();
1276 list.toggle_selection();
1277 assert!(list.selected_items.contains(&0));
1278
1279 list.select_next();
1280 list.toggle_selection();
1281 assert!(list.selected_items.contains(&1));
1282
1283 let selected = list.get_selected_items();
1284 assert_eq!(selected.len(), 2);
1285 }
1286
1287 #[test]
1288 fn test_list_widget_select_all() {
1289 let mut list = ListWidget::new().with_multi_select();
1290 list.add_item("item1");
1291 list.add_item("item2");
1292 list.add_item("item3");
1293
1294 list.select_all();
1295 assert_eq!(list.selected_items.len(), 3);
1296 }
1297
1298 #[test]
1299 fn test_list_widget_deselect_all() {
1300 let mut list = ListWidget::new().with_multi_select();
1301 list.add_item("item1");
1302 list.add_item("item2");
1303 list.add_item("item3");
1304
1305 list.select_all();
1306 assert_eq!(list.selected_items.len(), 3);
1307
1308 list.deselect_all();
1309 assert!(list.selected_items.is_empty());
1310 }
1311
1312 #[test]
1313 fn test_list_widget_filter() {
1314 let mut list = ListWidget::new();
1315 list.add_item("apple");
1316 list.add_item("apricot");
1317 list.add_item("banana");
1318 list.add_item("blueberry");
1319
1320 list.set_filter("ap");
1321 assert_eq!(list.filtered_items().len(), 2);
1322
1323 list.set_filter("b");
1324 assert_eq!(list.filtered_items().len(), 2);
1325
1326 list.clear_filter();
1327 assert_eq!(list.filtered_items().len(), 4);
1328 }
1329
1330 #[test]
1331 fn test_list_widget_visible_items() {
1332 let mut list = ListWidget::new();
1333 for i in 0..10 {
1334 list.add_item(format!("item{}", i));
1335 }
1336
1337 let visible = list.visible_items(5);
1338 assert_eq!(visible.len(), 5);
1339
1340 list.scroll = 3;
1341 let visible = list.visible_items(5);
1342 assert_eq!(visible.len(), 5);
1343 }
1344
1345 #[test]
1346 fn test_list_widget_add_items() {
1347 let mut list = ListWidget::new();
1348 let items = vec![
1349 "item1".to_string(),
1350 "item2".to_string(),
1351 "item3".to_string(),
1352 ];
1353 list.add_items(items);
1354
1355 assert_eq!(list.item_count(), 3);
1356 }
1357
1358 #[test]
1359 fn test_list_widget_clear() {
1360 let mut list = ListWidget::new();
1361 list.add_item("item1");
1362 list.add_item("item2");
1363 list.selected = Some(0);
1364
1365 list.clear();
1366 assert!(list.items.is_empty());
1367 assert!(list.selected.is_none());
1368 }
1369
1370 #[test]
1371 fn test_list_widget_is_empty() {
1372 let list = ListWidget::new();
1373 assert!(list.is_empty());
1374
1375 let mut list = ListWidget::new();
1376 list.add_item("item");
1377 assert!(!list.is_empty());
1378 }
1379
1380 #[test]
1381 fn test_dialog_widget() {
1382 let dialog = DialogWidget::new(DialogType::Input, "Title", "Message");
1383 assert_eq!(dialog.dialog_type, DialogType::Input);
1384 assert_eq!(dialog.title, "Title");
1385 assert!(dialog.is_pending());
1386 }
1387
1388 #[test]
1389 fn test_dialog_widget_input() {
1390 let mut dialog = DialogWidget::new(DialogType::Input, "Title", "Message");
1391 dialog.insert_char('h');
1392 dialog.insert_char('i');
1393
1394 assert_eq!(dialog.get_input(), "hi");
1395 }
1396
1397 #[test]
1398 fn test_dialog_widget_cursor_movement() {
1399 let mut dialog = DialogWidget::new(DialogType::Input, "Title", "Message");
1400 dialog.insert_char('h');
1401 dialog.insert_char('e');
1402 dialog.insert_char('l');
1403 dialog.insert_char('l');
1404 dialog.insert_char('o');
1405
1406 assert_eq!(dialog.cursor, 5);
1407
1408 dialog.cursor_left();
1409 assert_eq!(dialog.cursor, 4);
1410
1411 dialog.cursor_right();
1412 assert_eq!(dialog.cursor, 5);
1413
1414 dialog.cursor_start();
1415 assert_eq!(dialog.cursor, 0);
1416
1417 dialog.cursor_end();
1418 assert_eq!(dialog.cursor, 5);
1419 }
1420
1421 #[test]
1422 fn test_dialog_widget_delete() {
1423 let mut dialog = DialogWidget::new(DialogType::Input, "Title", "Message");
1424 dialog.insert_char('h');
1425 dialog.insert_char('e');
1426 dialog.insert_char('l');
1427 dialog.insert_char('l');
1428 dialog.insert_char('o');
1429
1430 dialog.cursor_start();
1431 dialog.delete();
1432 assert_eq!(dialog.get_input(), "ello");
1433 }
1434
1435 #[test]
1436 fn test_dialog_widget_backspace() {
1437 let mut dialog = DialogWidget::new(DialogType::Input, "Title", "Message");
1438 dialog.insert_char('h');
1439 dialog.insert_char('e');
1440 dialog.insert_char('l');
1441 dialog.insert_char('l');
1442 dialog.insert_char('o');
1443
1444 dialog.backspace();
1445 assert_eq!(dialog.get_input(), "hell");
1446 assert_eq!(dialog.cursor, 4);
1447 }
1448
1449 #[test]
1450 fn test_dialog_widget_confirm() {
1451 let mut dialog = DialogWidget::new(DialogType::Input, "Title", "Message");
1452 dialog.insert_char('t');
1453 dialog.insert_char('e');
1454 dialog.insert_char('s');
1455 dialog.insert_char('t');
1456
1457 dialog.confirm();
1458 assert!(dialog.is_confirmed());
1459 assert!(!dialog.is_pending());
1460 }
1461
1462 #[test]
1463 fn test_dialog_widget_cancel() {
1464 let mut dialog = DialogWidget::new(DialogType::Input, "Title", "Message");
1465 dialog.cancel();
1466 assert!(dialog.is_cancelled());
1467 assert!(!dialog.is_pending());
1468 }
1469
1470 #[test]
1471 fn test_dialog_widget_validation() {
1472 let mut dialog = DialogWidget::new(DialogType::Input, "Title", "Message")
1473 .with_validator(|input| !input.is_empty() && input.len() >= 3);
1474
1475 dialog.insert_char('a');
1476 dialog.insert_char('b');
1477 assert!(!dialog.validate());
1478
1479 dialog.insert_char('c');
1480 assert!(dialog.validate());
1481 }
1482
1483 #[test]
1484 fn test_dialog_widget_confirm_dialog() {
1485 let mut dialog = DialogWidget::new(DialogType::Confirm, "Confirm", "Are you sure?");
1486 assert!(dialog.confirmed.is_none());
1487
1488 dialog.confirm();
1489 assert_eq!(dialog.confirmed, Some(true));
1490 assert!(dialog.is_confirmed());
1491
1492 let mut dialog = DialogWidget::new(DialogType::Confirm, "Confirm", "Are you sure?");
1493 dialog.cancel();
1494 assert_eq!(dialog.confirmed, Some(false));
1495 assert!(dialog.is_cancelled());
1496 }
1497
1498 #[test]
1499 fn test_dialog_widget_clear_input() {
1500 let mut dialog = DialogWidget::new(DialogType::Input, "Title", "Message");
1501 dialog.insert_char('t');
1502 dialog.insert_char('e');
1503 dialog.insert_char('s');
1504 dialog.insert_char('t');
1505
1506 dialog.clear_input();
1507 assert!(dialog.get_input().is_empty());
1508 assert_eq!(dialog.cursor, 0);
1509 }
1510
1511 #[test]
1512 fn test_split_view_widget() {
1513 let mut split = SplitViewWidget::new();
1514 split.set_left("left content");
1515 split.set_right("right content");
1516
1517 assert_eq!(split.left_content, "left content");
1518 assert_eq!(split.right_content, "right content");
1519 assert_eq!(split.split_ratio, 50);
1520 }
1521
1522 #[test]
1523 fn test_split_view_adjust() {
1524 let mut split = SplitViewWidget::new();
1525 split.adjust_split(10);
1526 assert_eq!(split.split_ratio, 60);
1527
1528 split.adjust_split(-20);
1529 assert_eq!(split.split_ratio, 40);
1530 }
1531
1532 #[test]
1533 fn test_split_view_direction() {
1534 let split = SplitViewWidget::new();
1535 assert_eq!(split.direction, SplitDirection::Vertical);
1536
1537 let split = SplitViewWidget::horizontal();
1538 assert_eq!(split.direction, SplitDirection::Horizontal);
1539 }
1540
1541 #[test]
1542 fn test_split_view_panel_switching() {
1543 let mut split = SplitViewWidget::new();
1544 split.set_left("left");
1545 split.set_right("right");
1546
1547 assert_eq!(split.active_panel, 0);
1548 assert_eq!(split.active_content(), "left");
1549
1550 split.switch_panel();
1551 assert_eq!(split.active_panel, 1);
1552 assert_eq!(split.active_content(), "right");
1553
1554 split.switch_panel();
1555 assert_eq!(split.active_panel, 0);
1556 }
1557
1558 #[test]
1559 fn test_split_view_scrolling() {
1560 let mut split = SplitViewWidget::new();
1561 split.set_left("left content");
1562 split.set_right("right content");
1563
1564 assert_eq!(split.left_scroll, 0);
1565 split.scroll_down();
1566 assert_eq!(split.left_scroll, 1);
1567
1568 split.scroll_up();
1569 assert_eq!(split.left_scroll, 0);
1570
1571 split.switch_panel();
1572 split.scroll_down();
1573 assert_eq!(split.right_scroll, 1);
1574 }
1575
1576 #[test]
1577 fn test_tab_widget() {
1578 let mut tabs = TabWidget::new();
1579 tabs.add_tab("Tab 1");
1580 tabs.add_tab("Tab 2");
1581 tabs.add_tab("Tab 3");
1582
1583 assert_eq!(tabs.active, 0);
1584 tabs.select_next();
1585 assert_eq!(tabs.active, 1);
1586 tabs.select_prev();
1587 assert_eq!(tabs.active, 0);
1588 }
1589
1590 #[test]
1591 fn test_tab_widget_with_content() {
1592 let mut tabs = TabWidget::new();
1593 tabs.add_tab_with_content("Tab 1", "Content 1");
1594 tabs.add_tab_with_content("Tab 2", "Content 2");
1595
1596 assert_eq!(tabs.active_content(), Some(&"Content 1".to_string()));
1597
1598 tabs.select_next();
1599 assert_eq!(tabs.active_content(), Some(&"Content 2".to_string()));
1600 }
1601
1602 #[test]
1603 fn test_tab_widget_select_by_index() {
1604 let mut tabs = TabWidget::new();
1605 tabs.add_tab("Tab 1");
1606 tabs.add_tab("Tab 2");
1607 tabs.add_tab("Tab 3");
1608
1609 tabs.select_tab(2);
1610 assert_eq!(tabs.active, 2);
1611
1612 tabs.select_tab(0);
1613 assert_eq!(tabs.active, 0);
1614 }
1615
1616 #[test]
1617 fn test_tab_widget_close_tab() {
1618 let mut tabs = TabWidget::new();
1619 tabs.add_tab("Tab 1");
1620 tabs.add_tab("Tab 2");
1621 tabs.add_tab("Tab 3");
1622
1623 assert_eq!(tabs.tab_count(), 3);
1624
1625 tabs.close_tab(1);
1626 assert_eq!(tabs.tab_count(), 2);
1627 assert_eq!(tabs.active_tab(), Some(&"Tab 1".to_string()));
1628 }
1629
1630 #[test]
1631 fn test_tab_widget_close_active_tab() {
1632 let mut tabs = TabWidget::new();
1633 tabs.add_tab("Tab 1");
1634 tabs.add_tab("Tab 2");
1635 tabs.add_tab("Tab 3");
1636
1637 tabs.select_tab(2);
1639 assert_eq!(tabs.active, 2);
1640 tabs.close_active_tab();
1641 assert_eq!(tabs.tab_count(), 2);
1642 assert_eq!(tabs.active, 1);
1644 }
1645
1646 #[test]
1647 fn test_tab_widget_set_content() {
1648 let mut tabs = TabWidget::new();
1649 tabs.add_tab("Tab 1");
1650 tabs.set_active_content("New content");
1651
1652 assert_eq!(tabs.active_content(), Some(&"New content".to_string()));
1653 }
1654
1655 #[test]
1656 fn test_tab_widget_visible_tabs() {
1657 let mut tabs = TabWidget::new();
1658 for i in 0..10 {
1659 tabs.add_tab(format!("Tab {}", i));
1660 }
1661
1662 let visible = tabs.visible_tabs(5);
1663 assert_eq!(visible.len(), 5);
1664
1665 tabs.scroll = 3;
1666 let visible = tabs.visible_tabs(5);
1667 assert_eq!(visible.len(), 5);
1668 }
1669
1670 #[test]
1671 fn test_tab_widget_clear() {
1672 let mut tabs = TabWidget::new();
1673 tabs.add_tab("Tab 1");
1674 tabs.add_tab("Tab 2");
1675
1676 tabs.clear();
1677 assert!(tabs.is_empty());
1678 assert_eq!(tabs.active, 0);
1679 }
1680
1681 #[test]
1682 fn test_mode_indicator_creation() {
1683 let indicator = ModeIndicator::new(AppMode::Chat);
1684 assert_eq!(indicator.mode, AppMode::Chat);
1685 assert!(indicator.show_shortcut);
1686 }
1687
1688 #[test]
1689 fn test_mode_indicator_display_text() {
1690 let indicator = ModeIndicator::new(AppMode::Chat);
1691 let text = indicator.display_text();
1692 assert!(text.contains("Chat"));
1693 assert!(text.contains("Ctrl+1"));
1694 }
1695
1696 #[test]
1697 fn test_mode_indicator_short_text() {
1698 let indicator = ModeIndicator::new(AppMode::Command);
1699 assert_eq!(indicator.short_text(), "Command");
1700 }
1701
1702 #[test]
1703 fn test_mode_indicator_set_mode() {
1704 let mut indicator = ModeIndicator::new(AppMode::Chat);
1705 indicator.set_mode(AppMode::Diff);
1706 assert_eq!(indicator.mode, AppMode::Diff);
1707 }
1708
1709 #[test]
1710 fn test_mode_indicator_toggle_shortcut() {
1711 let mut indicator = ModeIndicator::new(AppMode::Chat);
1712 assert!(indicator.show_shortcut);
1713 indicator.toggle_shortcut_display();
1714 assert!(!indicator.show_shortcut);
1715 indicator.toggle_shortcut_display();
1716 assert!(indicator.show_shortcut);
1717 }
1718
1719 #[test]
1720 fn test_mode_indicator_get_capabilities() {
1721 let indicator = ModeIndicator::new(AppMode::Chat);
1722 let caps = indicator.get_capabilities();
1723 assert!(caps.contains(&"QuestionAnswering"));
1724 assert!(caps.contains(&"FreeformChat"));
1725 }
1726
1727 #[test]
1728 fn test_mode_indicator_capabilities_text() {
1729 let indicator = ModeIndicator::new(AppMode::Command);
1730 let text = indicator.capabilities_text();
1731 assert!(text.contains("Capabilities:"));
1732 assert!(text.contains("CodeGeneration"));
1733 }
1734
1735 #[test]
1736 fn test_mode_indicator_toggle_capabilities() {
1737 let mut indicator = ModeIndicator::new(AppMode::Chat);
1738 assert!(!indicator.show_capabilities);
1739 indicator.toggle_capabilities_display();
1740 assert!(indicator.show_capabilities);
1741 indicator.toggle_capabilities_display();
1742 assert!(!indicator.show_capabilities);
1743 }
1744
1745 #[test]
1746 fn test_mode_indicator_show_hide_capabilities() {
1747 let mut indicator = ModeIndicator::new(AppMode::Chat);
1748 assert!(!indicator.show_capabilities);
1749
1750 indicator.show_capabilities_enabled();
1751 assert!(indicator.show_capabilities);
1752
1753 indicator.hide_capabilities_enabled();
1754 assert!(!indicator.show_capabilities);
1755 }
1756
1757 #[test]
1758 fn test_mode_selection_menu_creation() {
1759 let menu = ModeSelectionMenu::new();
1760 assert!(!menu.open);
1761 assert_eq!(menu.modes.len(), 4);
1762 assert_eq!(menu.selected_mode(), AppMode::Chat);
1763 }
1764
1765 #[test]
1766 fn test_mode_selection_menu_open_close() {
1767 let mut menu = ModeSelectionMenu::new();
1768 assert!(!menu.open);
1769
1770 menu.open(AppMode::Chat);
1771 assert!(menu.open);
1772
1773 menu.close();
1774 assert!(!menu.open);
1775 }
1776
1777 #[test]
1778 fn test_mode_selection_menu_navigation() {
1779 let mut menu = ModeSelectionMenu::new();
1780 menu.open(AppMode::Chat);
1781
1782 assert_eq!(menu.selected_mode(), AppMode::Chat);
1783 menu.select_next();
1784 assert_eq!(menu.selected_mode(), AppMode::Command);
1785 menu.select_next();
1786 assert_eq!(menu.selected_mode(), AppMode::Diff);
1787 menu.select_prev();
1788 assert_eq!(menu.selected_mode(), AppMode::Command);
1789 }
1790
1791 #[test]
1792 fn test_mode_selection_menu_wrap_around() {
1793 let mut menu = ModeSelectionMenu::new();
1794 menu.open(AppMode::Help);
1795
1796 assert_eq!(menu.selected_mode(), AppMode::Help);
1797 menu.select_next();
1798 assert_eq!(menu.selected_mode(), AppMode::Chat);
1799
1800 menu.select_prev();
1801 assert_eq!(menu.selected_mode(), AppMode::Help);
1802 }
1803
1804 #[test]
1805 fn test_mode_selection_menu_confirm() {
1806 let mut menu = ModeSelectionMenu::new();
1807 menu.open(AppMode::Chat);
1808 menu.select_next();
1809
1810 let selected = menu.confirm_switch();
1811 assert_eq!(selected, AppMode::Command);
1812 assert!(!menu.open);
1813 }
1814
1815 #[test]
1816 fn test_mode_selection_menu_descriptions() {
1817 let menu = ModeSelectionMenu::new();
1818 let descriptions = menu.get_mode_descriptions();
1819 assert_eq!(descriptions.len(), 4);
1820 assert!(descriptions[0].1.contains("Chat"));
1821 }
1822
1823 #[test]
1824 fn test_mode_selection_menu_shortcuts() {
1825 let menu = ModeSelectionMenu::new();
1826 let shortcuts = menu.get_shortcuts();
1827 assert_eq!(shortcuts.len(), 4);
1828 assert_eq!(shortcuts[0].0, "Ctrl+1");
1829 }
1830
1831 #[test]
1832 fn test_vim_keybindings_creation() {
1833 let vim = VimKeybindings::new();
1834 assert!(!vim.enabled);
1835 assert_eq!(vim.mode, VimMode::Normal);
1836 assert!(vim.command_buffer.is_empty());
1837 }
1838
1839 #[test]
1840 fn test_vim_keybindings_enable_disable() {
1841 let mut vim = VimKeybindings::new();
1842 assert!(!vim.enabled);
1843
1844 vim.enable();
1845 assert!(vim.enabled);
1846 assert_eq!(vim.mode, VimMode::Normal);
1847
1848 vim.disable();
1849 assert!(!vim.enabled);
1850 }
1851
1852 #[test]
1853 fn test_vim_keybindings_toggle() {
1854 let mut vim = VimKeybindings::new();
1855 assert!(!vim.enabled);
1856
1857 vim.toggle();
1858 assert!(vim.enabled);
1859
1860 vim.toggle();
1861 assert!(!vim.enabled);
1862 }
1863
1864 #[test]
1865 fn test_vim_keybindings_mode_switching() {
1866 let mut vim = VimKeybindings::new();
1867 vim.enable();
1868
1869 assert_eq!(vim.mode, VimMode::Normal);
1870
1871 vim.enter_insert();
1872 assert_eq!(vim.mode, VimMode::Insert);
1873
1874 vim.enter_visual();
1875 assert_eq!(vim.mode, VimMode::Visual);
1876
1877 vim.enter_command();
1878 assert_eq!(vim.mode, VimMode::Command);
1879
1880 vim.enter_normal();
1881 assert_eq!(vim.mode, VimMode::Normal);
1882 }
1883
1884 #[test]
1885 fn test_vim_keybindings_command_buffer() {
1886 let mut vim = VimKeybindings::new();
1887 vim.enable();
1888 vim.enter_command();
1889
1890 vim.add_to_command('w');
1891 vim.add_to_command('q');
1892
1893 assert_eq!(vim.get_command(), "wq");
1894
1895 vim.clear_command();
1896 assert!(vim.get_command().is_empty());
1897 }
1898
1899 #[test]
1900 fn test_vim_keybindings_mode_checks() {
1901 let mut vim = VimKeybindings::new();
1902 vim.enable();
1903
1904 assert!(vim.is_normal());
1905 assert!(!vim.is_insert());
1906 assert!(!vim.is_visual());
1907 assert!(!vim.is_command());
1908
1909 vim.enter_insert();
1910 assert!(!vim.is_normal());
1911 assert!(vim.is_insert());
1912
1913 vim.enter_visual();
1914 assert!(vim.is_visual());
1915
1916 vim.enter_command();
1917 assert!(vim.is_command());
1918 }
1919
1920 #[test]
1921 fn test_vim_keybindings_disabled_mode_checks() {
1922 let vim = VimKeybindings::new();
1923 assert!(!vim.is_normal());
1924 assert!(!vim.is_insert());
1925 assert!(!vim.is_visual());
1926 assert!(!vim.is_command());
1927 }
1928
1929 #[test]
1930 fn test_vim_keybindings_enter_normal_clears_command() {
1931 let mut vim = VimKeybindings::new();
1932 vim.enable();
1933 vim.enter_command();
1934 vim.add_to_command('w');
1935 vim.add_to_command('q');
1936
1937 assert!(!vim.get_command().is_empty());
1938
1939 vim.enter_normal();
1940 assert!(vim.get_command().is_empty());
1941 }
1942
1943 #[test]
1944 fn test_vim_keybindings_disable_resets_mode() {
1945 let mut vim = VimKeybindings::new();
1946 vim.enable();
1947 vim.enter_command();
1948 vim.add_to_command('t');
1949 vim.add_to_command('e');
1950 vim.add_to_command('s');
1951 vim.add_to_command('t');
1952
1953 vim.disable();
1954 assert_eq!(vim.mode, VimMode::Normal);
1955 assert!(vim.get_command().is_empty());
1956 }
1957}