1use crate::{mode::Mode, SwitchMode, VimState};
2use gpui::{actions, MutableAppContext, ViewContext};
3use workspace::Workspace;
4
5actions!(vim, [MoveToStart]);
6
7pub fn init(cx: &mut MutableAppContext) {
8 cx.add_action(move_to_start);
9}
10
11fn move_to_start(_: &mut Workspace, _: &MoveToStart, cx: &mut ViewContext<Workspace>) {
12 VimState::update_global(cx, |state, cx| {
13 state.update_active_editor(cx, |editor, cx| {
14 editor.move_to_beginning(&editor::MoveToBeginning, cx);
15 });
16 state.switch_mode(&SwitchMode(Mode::normal()), cx);
17 })
18}
19
20#[cfg(test)]
21mod test {
22 use indoc::indoc;
23
24 use crate::{
25 mode::{Mode, NormalState},
26 vim_test_context::VimTestContext,
27 };
28
29 #[gpui::test]
30 async fn test_g_prefix_and_abort(cx: &mut gpui::TestAppContext) {
31 let mut cx = VimTestContext::new(cx, true, "").await;
32
33 // Can abort with escape to get back to normal mode
34 cx.simulate_keystroke("g");
35 assert_eq!(cx.mode(), Mode::Normal(NormalState::GPrefix));
36 cx.simulate_keystroke("escape");
37 assert_eq!(cx.mode(), Mode::normal());
38 }
39
40 #[gpui::test]
41 async fn test_move_to_start(cx: &mut gpui::TestAppContext) {
42 let initial_content = indoc! {"
43 The quick
44
45 brown fox jumps
46 over the lazy dog"};
47 let mut cx = VimTestContext::new(cx, true, initial_content).await;
48
49 // Jump to the end to
50 cx.simulate_keystroke("shift-G");
51 cx.assert_editor_state(indoc! {"
52 The quick
53
54 brown fox jumps
55 over the lazy do|g"});
56
57 // Jump to the start
58 cx.simulate_keystrokes(&["g", "g"]);
59 cx.assert_editor_state(indoc! {"
60 |The quick
61
62 brown fox jumps
63 over the lazy dog"});
64 assert_eq!(cx.mode(), Mode::normal());
65
66 // Repeat action doesn't change
67 cx.simulate_keystrokes(&["g", "g"]);
68 cx.assert_editor_state(indoc! {"
69 |The quick
70
71 brown fox jumps
72 over the lazy dog"});
73 assert_eq!(cx.mode(), Mode::normal());
74 }
75}