1use editor::{EditorBlurred, EditorFocused, EditorMode, EditorReleased};
2use gpui::MutableAppContext;
3
4use crate::{state::Mode, Vim};
5
6pub fn init(cx: &mut MutableAppContext) {
7 cx.subscribe_global(focused).detach();
8 cx.subscribe_global(blurred).detach();
9 cx.subscribe_global(released).detach();
10}
11
12fn focused(EditorFocused(editor): &EditorFocused, cx: &mut MutableAppContext) {
13 Vim::update(cx, |vim, cx| {
14 if let Some(previously_active_editor) = vim
15 .active_editor
16 .as_ref()
17 .and_then(|editor| editor.upgrade(cx))
18 {
19 vim.unhook_vim_settings(previously_active_editor, cx);
20 }
21
22 vim.active_editor = Some(editor.downgrade());
23 dbg!("Active editor changed", editor.read(cx).mode());
24 vim.editor_subscription = Some(cx.subscribe(editor, |editor, event, cx| {
25 if editor.read(cx).leader_replica_id().is_none() {
26 if let editor::Event::SelectionsChanged { local: true } = event {
27 let newest_empty = editor.read(cx).selections.newest::<usize>(cx).is_empty();
28 local_selections_changed(newest_empty, cx);
29 }
30 }
31 }));
32
33 if vim.enabled {
34 let editor = editor.read(cx);
35 let editor_mode = editor.mode();
36 let newest_selection_empty = editor.selections.newest::<usize>(cx).is_empty();
37
38 if editor_mode == EditorMode::Full && !newest_selection_empty {
39 vim.switch_mode(Mode::Visual { line: false }, true, cx);
40 }
41 }
42
43 vim.sync_vim_settings(cx);
44 });
45}
46
47fn blurred(EditorBlurred(editor): &EditorBlurred, cx: &mut MutableAppContext) {
48 Vim::update(cx, |vim, cx| {
49 if let Some(previous_editor) = vim.active_editor.clone() {
50 if previous_editor == editor.clone() {
51 vim.active_editor = None;
52 }
53 }
54 vim.unhook_vim_settings(editor.clone(), cx);
55 })
56}
57
58fn released(EditorReleased(editor): &EditorReleased, cx: &mut MutableAppContext) {
59 cx.update_default_global(|vim: &mut Vim, _| {
60 if let Some(previous_editor) = vim.active_editor.clone() {
61 if previous_editor == editor.clone() {
62 vim.active_editor = None;
63 }
64 }
65 });
66}
67
68fn local_selections_changed(newest_empty: bool, cx: &mut MutableAppContext) {
69 Vim::update(cx, |vim, cx| {
70 if vim.enabled && vim.state.mode == Mode::Normal && !newest_empty {
71 vim.switch_mode(Mode::Visual { line: false }, false, cx)
72 }
73 })
74}