mode_indicator.rs

 1use gpui::{div, AnyElement, Element, IntoElement, Render, ViewContext};
 2use settings::{Settings, SettingsStore};
 3use workspace::{item::ItemHandle, ui::Label, StatusItemView};
 4
 5use crate::{state::Mode, Vim, VimModeSetting};
 6
 7pub struct ModeIndicator {
 8    pub mode: Option<Mode>,
 9    // _subscription: Subscription,
10}
11
12impl ModeIndicator {
13    pub fn new(cx: &mut ViewContext<Self>) -> Self {
14        cx.observe_global::<Vim>(|this, cx| this.set_mode(Vim::read(cx).state().mode, cx))
15            .detach();
16
17        cx.observe_global::<SettingsStore>(move |mode_indicator, cx| {
18            if VimModeSetting::get_global(cx).0 {
19                mode_indicator.mode = cx
20                    .has_global::<Vim>()
21                    .then(|| cx.global::<Vim>().state().mode);
22            } else {
23                mode_indicator.mode.take();
24            }
25        })
26        .detach();
27
28        // Vim doesn't exist in some tests
29        let mode = cx
30            .has_global::<Vim>()
31            .then(|| {
32                let vim = cx.global::<Vim>();
33                vim.enabled.then(|| vim.state().mode)
34            })
35            .flatten();
36
37        Self {
38            mode,
39            //    _subscription,
40        }
41    }
42
43    pub fn set_mode(&mut self, mode: Mode, cx: &mut ViewContext<Self>) {
44        if self.mode != Some(mode) {
45            self.mode = Some(mode);
46            cx.notify();
47        }
48    }
49}
50
51impl Render for ModeIndicator {
52    type Element = AnyElement;
53
54    fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement {
55        let Some(mode) = self.mode.as_ref() else {
56            return div().into_any();
57        };
58
59        let text = match mode {
60            Mode::Normal => "-- NORMAL --",
61            Mode::Insert => "-- INSERT --",
62            Mode::Visual => "-- VISUAL --",
63            Mode::VisualLine => "-- VISUAL LINE --",
64            Mode::VisualBlock => "-- VISUAL BLOCK --",
65        };
66        Label::new(text).into_any_element()
67    }
68}
69
70impl StatusItemView for ModeIndicator {
71    fn set_active_pane_item(
72        &mut self,
73        _active_pane_item: Option<&dyn ItemHandle>,
74        _cx: &mut ViewContext<Self>,
75    ) {
76        // nothing to do.
77    }
78}