1mod neovim_backed_binding_test_context;
2mod neovim_backed_test_context;
3mod neovim_connection;
4mod vim_binding_test_context;
5mod vim_test_context;
6
7use command_palette::CommandPalette;
8pub use neovim_backed_binding_test_context::*;
9pub use neovim_backed_test_context::*;
10pub use vim_binding_test_context::*;
11pub use vim_test_context::*;
12
13use indoc::indoc;
14use search::BufferSearchBar;
15
16use crate::state::Mode;
17
18#[gpui::test]
19async fn test_initially_disabled(cx: &mut gpui::TestAppContext) {
20 let mut cx = VimTestContext::new(cx, false).await;
21 cx.simulate_keystrokes(["h", "j", "k", "l"]);
22 cx.assert_editor_state("hjklˇ");
23}
24
25#[gpui::test]
26async fn test_neovim(cx: &mut gpui::TestAppContext) {
27 let mut cx = NeovimBackedTestContext::new(cx).await;
28
29 cx.simulate_shared_keystroke("i").await;
30 cx.assert_state_matches().await;
31 cx.simulate_shared_keystrokes([
32 "shift-T", "e", "s", "t", " ", "t", "e", "s", "t", "escape", "0", "d", "w",
33 ])
34 .await;
35 cx.assert_state_matches().await;
36 cx.assert_editor_state("ˇtest");
37}
38
39#[gpui::test]
40async fn test_toggle_through_settings(cx: &mut gpui::TestAppContext) {
41 let mut cx = VimTestContext::new(cx, true).await;
42
43 cx.simulate_keystroke("i");
44 assert_eq!(cx.mode(), Mode::Insert);
45
46 // Editor acts as though vim is disabled
47 cx.disable_vim();
48 cx.simulate_keystrokes(["h", "j", "k", "l"]);
49 cx.assert_editor_state("hjklˇ");
50
51 // Selections aren't changed if editor is blurred but vim-mode is still disabled.
52 cx.set_state("«hjklˇ»", Mode::Normal);
53 cx.assert_editor_state("«hjklˇ»");
54 cx.update_editor(|_, cx| cx.blur());
55 cx.assert_editor_state("«hjklˇ»");
56 cx.update_editor(|_, cx| cx.focus_self());
57 cx.assert_editor_state("«hjklˇ»");
58
59 // Enabling dynamically sets vim mode again and restores normal mode
60 cx.enable_vim();
61 assert_eq!(cx.mode(), Mode::Normal);
62 cx.simulate_keystrokes(["h", "h", "h", "l"]);
63 assert_eq!(cx.buffer_text(), "hjkl".to_owned());
64 cx.assert_editor_state("hˇjkl");
65 cx.simulate_keystrokes(["i", "T", "e", "s", "t"]);
66 cx.assert_editor_state("hTestˇjkl");
67
68 // Disabling and enabling resets to normal mode
69 assert_eq!(cx.mode(), Mode::Insert);
70 cx.disable_vim();
71 cx.enable_vim();
72 assert_eq!(cx.mode(), Mode::Normal);
73}
74
75#[gpui::test]
76async fn test_buffer_search(cx: &mut gpui::TestAppContext) {
77 let mut cx = VimTestContext::new(cx, true).await;
78
79 cx.set_state(
80 indoc! {"
81 The quick brown
82 fox juˇmps over
83 the lazy dog"},
84 Mode::Normal,
85 );
86 cx.simulate_keystroke("/");
87
88 let search_bar = cx.workspace(|workspace, cx| {
89 workspace
90 .active_pane()
91 .read(cx)
92 .toolbar()
93 .read(cx)
94 .item_of_type::<BufferSearchBar>()
95 .expect("Buffer search bar should be deployed")
96 });
97
98 search_bar.read_with(cx.cx, |bar, cx| {
99 assert_eq!(bar.query_editor.read(cx).text(cx), "jumps");
100 })
101}
102
103#[gpui::test]
104async fn test_count_down(cx: &mut gpui::TestAppContext) {
105 let mut cx = VimTestContext::new(cx, true).await;
106
107 cx.set_state(indoc! {"aˇa\nbb\ncc\ndd\nee"}, Mode::Normal);
108 cx.simulate_keystrokes(["2", "down"]);
109 cx.assert_editor_state("aa\nbb\ncˇc\ndd\nee");
110 cx.simulate_keystrokes(["9", "down"]);
111 cx.assert_editor_state("aa\nbb\ncc\ndd\neˇe");
112}
113
114#[gpui::test]
115async fn test_end_of_document_710(cx: &mut gpui::TestAppContext) {
116 let mut cx = VimTestContext::new(cx, true).await;
117
118 // goes to end by default
119 cx.set_state(indoc! {"aˇa\nbb\ncc"}, Mode::Normal);
120 cx.simulate_keystrokes(["shift-g"]);
121 cx.assert_editor_state("aa\nbb\ncˇc");
122
123 // can go to line 1 (https://github.com/zed-industries/community/issues/710)
124 cx.simulate_keystrokes(["1", "shift-g"]);
125 cx.assert_editor_state("aˇa\nbb\ncc");
126}
127
128#[gpui::test]
129async fn test_indent_outdent(cx: &mut gpui::TestAppContext) {
130 let mut cx = VimTestContext::new(cx, true).await;
131
132 // works in normal mode
133 cx.set_state(indoc! {"aa\nbˇb\ncc"}, Mode::Normal);
134 cx.simulate_keystrokes([">", ">"]);
135 cx.assert_editor_state("aa\n bˇb\ncc");
136 cx.simulate_keystrokes(["<", "<"]);
137 cx.assert_editor_state("aa\nbˇb\ncc");
138
139 // works in visuial mode
140 cx.simulate_keystrokes(["shift-v", "down", ">"]);
141 cx.assert_editor_state("aa\n b«b\n cˇ»c");
142}
143
144#[gpui::test]
145async fn test_escape_command_palette(cx: &mut gpui::TestAppContext) {
146 let mut cx = VimTestContext::new(cx, true).await;
147
148 cx.set_state("aˇbc\n", Mode::Normal);
149 cx.simulate_keystrokes(["i", "cmd-shift-p"]);
150
151 assert!(cx.workspace(|workspace, _| workspace.modal::<CommandPalette>().is_some()));
152 cx.simulate_keystroke("escape");
153 assert!(!cx.workspace(|workspace, _| workspace.modal::<CommandPalette>().is_some()));
154 cx.assert_state("aˇbc\n", Mode::Insert);
155}