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