1use editor::{EditorBlurred, EditorFocused, EditorMode, EditorReleased, Event};
2use gpui::{AppContext, WindowContext};
3
4use crate::{state::Mode, Vim};
5
6pub fn init(cx: &mut AppContext) {
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 AppContext) {
13 cx.update_window(editor.window_id(), |cx| {
14 Vim::update(cx, |vim, cx| {
15 vim.update_active_editor(cx, |previously_active_editor, cx| {
16 Vim::unhook_vim_settings(previously_active_editor, cx);
17 });
18
19 vim.active_editor = Some(editor.downgrade());
20 vim.editor_subscription = Some(cx.subscribe(editor, |editor, event, cx| match event {
21 Event::SelectionsChanged { local: true } => {
22 let editor = editor.read(cx);
23 if editor.leader_replica_id().is_none() {
24 let newest_empty = editor.selections.newest::<usize>(cx).is_empty();
25 local_selections_changed(newest_empty, cx);
26 }
27 }
28 Event::InputIgnored { text } => {
29 Vim::active_editor_input_ignored(text.clone(), cx);
30 }
31 _ => {}
32 }));
33
34 if vim.enabled {
35 let editor = editor.read(cx);
36 let editor_mode = editor.mode();
37 let newest_selection_empty = editor.selections.newest::<usize>(cx).is_empty();
38
39 if editor_mode == EditorMode::Full && !newest_selection_empty {
40 vim.switch_mode(Mode::Visual { line: false }, true, cx);
41 }
42 }
43
44 vim.sync_vim_settings(cx);
45 });
46 });
47}
48
49fn blurred(EditorBlurred(editor): &EditorBlurred, cx: &mut AppContext) {
50 cx.update_window(editor.window_id(), |cx| {
51 Vim::update(cx, |vim, cx| {
52 if let Some(previous_editor) = vim.active_editor.clone() {
53 if previous_editor == editor.clone() {
54 vim.active_editor = None;
55 }
56 }
57
58 cx.update_window(editor.window_id(), |cx| {
59 editor.update(cx, |editor, cx| Vim::unhook_vim_settings(editor, cx))
60 });
61 });
62 });
63}
64
65fn released(EditorReleased(editor): &EditorReleased, cx: &mut AppContext) {
66 cx.update_window(editor.window_id(), |cx| {
67 cx.update_default_global(|vim: &mut Vim, _| {
68 if let Some(previous_editor) = vim.active_editor.clone() {
69 if previous_editor == editor.clone() {
70 vim.active_editor = None;
71 }
72 }
73 });
74 });
75}
76
77fn local_selections_changed(newest_empty: bool, cx: &mut WindowContext) {
78 Vim::update(cx, |vim, cx| {
79 if vim.enabled && vim.state.mode == Mode::Normal && !newest_empty {
80 vim.switch_mode(Mode::Visual { line: false }, false, cx)
81 }
82 })
83}