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
 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    fn render(&mut self, _: &mut ViewContext<Self>) -> impl IntoElement {
51        let Some(mode) = self.mode.as_ref() else {
52            return div().into_any();
53        };
54
55        let text = match mode {
56            Mode::Normal => "-- NORMAL --",
57            Mode::Insert => "-- INSERT --",
58            Mode::Visual => "-- VISUAL --",
59            Mode::VisualLine => "-- VISUAL LINE --",
60            Mode::VisualBlock => "-- VISUAL BLOCK --",
61        };
62        Label::new(text).size(LabelSize::Small).into_any_element()
63    }
64}
65
66impl StatusItemView for ModeIndicator {
67    fn set_active_pane_item(
68        &mut self,
69        _active_pane_item: Option<&dyn ItemHandle>,
70        _cx: &mut ViewContext<Self>,
71    ) {
72        // nothing to do.
73    }
74}