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}