mode_indicator.rs

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