editor_events.rs

  1use crate::Vim;
  2use editor::{Editor, EditorBlurred, EditorEvent, EditorFocused, EditorReleased};
  3use gpui::{AppContext, Entity, EntityId, View, ViewContext, WindowContext};
  4use workspace::item::WeakItemHandle;
  5
  6pub fn init(cx: &mut AppContext) {
  7    cx.observe_new_views(|_, cx: &mut ViewContext<Editor>| {
  8        let editor = cx.view().clone();
  9        cx.subscribe(&editor, |_, editor, event: &EditorEvent, cx| match event {
 10            EditorEvent::Focused => cx.window_context().defer(|cx| focused(editor, cx)),
 11            EditorEvent::Blurred => cx.window_context().defer(|cx| blurred(editor, cx)),
 12            _ => {}
 13        })
 14        .detach();
 15
 16        let id = cx.view().entity_id();
 17        cx.on_release(move |_, cx| released(id, cx)).detach();
 18    })
 19    .detach();
 20    // todo!()
 21    // cx.subscribe_global(focused).detach();
 22    // cx.subscribe_global(blurred).detach();
 23    // cx.subscribe_global(released).detach();
 24}
 25
 26fn focused(editor: View<Editor>, cx: &mut WindowContext) {
 27    if let Some(previously_active_editor) = Vim::read(cx).active_editor.clone() {
 28        Vim::update(cx, |vim, cx| {
 29            vim.update_active_editor(cx, |previously_active_editor, cx| {
 30                vim.unhook_vim_settings(previously_active_editor, cx)
 31            });
 32        });
 33    }
 34
 35    Vim::update(cx, |vim, cx| {
 36        vim.set_active_editor(editor.clone(), cx);
 37        if vim.enabled {
 38            // todo!()
 39            // cx.emit_global(VimEvent::ModeChanged {
 40            //     mode: vim.state().mode,
 41            // });
 42        }
 43    });
 44}
 45
 46fn blurred(editor: View<Editor>, cx: &mut WindowContext) {
 47    Vim::update(cx, |vim, cx| {
 48        vim.workspace_state.recording = false;
 49        vim.workspace_state.recorded_actions.clear();
 50        if let Some(previous_editor) = vim.active_editor.clone() {
 51            if previous_editor
 52                .upgrade()
 53                .is_some_and(|previous| previous == editor.clone())
 54            {
 55                vim.clear_operator(cx);
 56                vim.active_editor = None;
 57                vim.editor_subscription = None;
 58            }
 59        }
 60
 61        editor.update(cx, |editor, cx| vim.unhook_vim_settings(editor, cx))
 62    });
 63}
 64
 65fn released(entity_id: EntityId, cx: &mut WindowContext) {
 66    Vim::update(cx, |vim, _| {
 67        if vim
 68            .active_editor
 69            .as_ref()
 70            .is_some_and(|previous| previous.entity_id() == entity_id)
 71        {
 72            vim.active_editor = None;
 73            vim.editor_subscription = None;
 74        }
 75        vim.editor_states.remove(&entity_id)
 76    });
 77}
 78
 79// #[cfg(test)]
 80// mod test {
 81//     use crate::{test::VimTestContext, Vim};
 82//     use editor::Editor;
 83//     use gpui::{Context, Entity};
 84//     use language::Buffer;
 85
 86//     // regression test for blur called with a different active editor
 87//     #[gpui::test]
 88//     async fn test_blur_focus(cx: &mut gpui::TestAppContext) {
 89//         let mut cx = VimTestContext::new(cx, true).await;
 90
 91//         let buffer = cx.build_model(|_| Buffer::new(0, 0, "a = 1\nb = 2\n"));
 92//         let window2 = cx.add_window(|cx| Editor::for_buffer(buffer, None, cx));
 93//         let editor2 = cx
 94//             .update(|cx| window2.update(cx, |editor, cx| cx.view()))
 95//             .unwrap();
 96
 97//         cx.update(|cx| {
 98//             let vim = Vim::read(cx);
 99//             assert_eq!(
100//                 vim.active_editor.unwrap().entity_id().unwrap(),
101//                 editor2.entity_id()
102//             )
103//         });
104
105//         // no panic when blurring an editor in a different window.
106//         cx.update_editor(|editor1, cx| {
107//             editor1.focus_out(cx.handle().into_any(), cx);
108//         });
109//     }
110// }