mode_indicator.rs

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