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        if !cx.has_global::<Vim>() {
32            return;
33        }
34
35        let vim = Vim::read(cx);
36        if vim.enabled {
37            self.mode = Some(vim.state().mode);
38        } else {
39            self.mode = None;
40        }
41    }
42}
43
44impl Render for ModeIndicator {
45    fn render(&mut self, _: &mut ViewContext<Self>) -> impl IntoElement {
46        let Some(mode) = self.mode.as_ref() else {
47            return div().into_any();
48        };
49
50        let text = match mode {
51            Mode::Normal => "-- NORMAL --",
52            Mode::Insert => "-- INSERT --",
53            Mode::Visual => "-- VISUAL --",
54            Mode::VisualLine => "-- VISUAL LINE --",
55            Mode::VisualBlock => "-- VISUAL BLOCK --",
56        };
57        Label::new(text).size(LabelSize::Small).into_any_element()
58    }
59}
60
61impl StatusItemView for ModeIndicator {
62    fn set_active_pane_item(
63        &mut self,
64        _active_pane_item: Option<&dyn ItemHandle>,
65        _cx: &mut ViewContext<Self>,
66    ) {
67        // nothing to do.
68    }
69}