mode_indicator.rs

 1use gpui::{
 2    elements::{Empty, Label},
 3    AnyElement, Element, Entity, View, ViewContext,
 4};
 5use workspace::{item::ItemHandle, StatusItemView};
 6
 7use crate::{state::Mode, Vim};
 8
 9pub struct ModeIndicator {
10    mode: Option<Mode>,
11}
12
13impl ModeIndicator {
14    pub fn new(cx: &mut ViewContext<Self>) -> Self {
15        cx.observe_global::<Vim, _>(|this, cx| {
16            let vim = Vim::read(cx);
17            if vim.enabled {
18                this.set_mode(Some(Vim::read(cx).state.mode), cx)
19            } else {
20                this.set_mode(None, cx)
21            }
22        })
23        .detach();
24        Self { mode: None }
25    }
26
27    pub fn set_mode(&mut self, mode: Option<Mode>, cx: &mut ViewContext<Self>) {
28        if mode != self.mode {
29            self.mode = mode;
30            cx.notify();
31        }
32    }
33}
34
35impl Entity for ModeIndicator {
36    type Event = ();
37}
38
39impl View for ModeIndicator {
40    fn ui_name() -> &'static str {
41        "ModeIndicator"
42    }
43
44    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
45        if let Some(mode) = self.mode {
46            let theme = &theme::current(cx).workspace.status_bar;
47            let text = match mode {
48                Mode::Normal => "",
49                Mode::Insert => "--- INSERT ---",
50                Mode::Visual { line: false } => "--- VISUAL ---",
51                Mode::Visual { line: true } => "--- VISUAL LINE ---",
52            };
53            Label::new(text, theme.vim_mode.clone()).into_any()
54        } else {
55            Empty::new().into_any()
56        }
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}