1use editor::{EditorBlurred, EditorCreated, EditorFocused, EditorMode, EditorReleased};
2use gpui::MutableAppContext;
3
4use crate::{state::Mode, Vim};
5
6pub fn init(cx: &mut MutableAppContext) {
7 cx.subscribe_global(editor_created).detach();
8 cx.subscribe_global(editor_focused).detach();
9 cx.subscribe_global(editor_blurred).detach();
10 cx.subscribe_global(editor_released).detach();
11}
12
13fn editor_created(EditorCreated(editor): &EditorCreated, cx: &mut MutableAppContext) {
14 cx.update_default_global(|vim: &mut Vim, cx| {
15 vim.editors.insert(editor.id(), editor.downgrade());
16 vim.sync_vim_settings(cx);
17 })
18}
19
20fn editor_focused(EditorFocused(editor): &EditorFocused, cx: &mut MutableAppContext) {
21 Vim::update(cx, |vim, cx| {
22 vim.active_editor = Some(editor.downgrade());
23 vim.selection_subscription = Some(cx.subscribe(editor, |editor, event, cx| {
24 if editor.read(cx).leader_replica_id().is_none() {
25 match event {
26 editor::Event::SelectionsChanged { local: true } => {
27 let newest_empty =
28 editor.read(cx).selections.newest::<usize>(cx).is_empty();
29 editor_local_selections_changed(newest_empty, cx);
30 }
31 editor::Event::IgnoredInput => {
32 Vim::update(cx, |vim, cx| {
33 if vim.active_operator().is_some() {
34 vim.clear_operator(cx);
35 }
36 });
37 }
38 _ => (),
39 }
40 }
41 }));
42
43 if !vim.enabled {
44 return;
45 }
46
47 let editor = editor.read(cx);
48 let editor_mode = editor.mode();
49 let newest_selection_empty = editor.selections.newest::<usize>(cx).is_empty();
50
51 if editor_mode != EditorMode::Full {
52 vim.switch_mode(Mode::Insert, true, cx);
53 } else if !newest_selection_empty {
54 vim.switch_mode(Mode::Visual { line: false }, true, cx);
55 }
56 });
57}
58
59fn editor_blurred(EditorBlurred(editor): &EditorBlurred, cx: &mut MutableAppContext) {
60 Vim::update(cx, |vim, cx| {
61 if let Some(previous_editor) = vim.active_editor.clone() {
62 if previous_editor == editor.clone() {
63 vim.active_editor = None;
64 }
65 }
66 vim.sync_vim_settings(cx);
67 })
68}
69
70fn editor_released(EditorReleased(editor): &EditorReleased, cx: &mut MutableAppContext) {
71 cx.update_default_global(|vim: &mut Vim, _| {
72 vim.editors.remove(&editor.id());
73 if let Some(previous_editor) = vim.active_editor.clone() {
74 if previous_editor == editor.clone() {
75 vim.active_editor = None;
76 }
77 }
78 });
79}
80
81fn editor_local_selections_changed(newest_empty: bool, cx: &mut MutableAppContext) {
82 Vim::update(cx, |vim, cx| {
83 if vim.enabled && vim.state.mode == Mode::Normal && !newest_empty {
84 vim.switch_mode(Mode::Visual { line: false }, false, cx)
85 }
86 })
87}