1use gpui::{div, AnyElement, Div, Element, Entity, IntoElement, Render, Subscription, ViewContext};
2use settings::{Settings, SettingsStore};
3use workspace::{item::ItemHandle, ui::Label, StatusItemView};
4
5use crate::{state::Mode, Vim, VimEvent, VimModeSetting};
6
7pub struct ModeIndicator {
8 pub mode: Option<Mode>,
9 // _subscription: Subscription,
10}
11
12impl ModeIndicator {
13 pub fn new(cx: &mut ViewContext<Self>) -> Self {
14 let handle = cx.view().downgrade();
15
16 // let _subscription = cx.subscribe_global::<VimEvent, _>(move |&event, cx| {
17 // if let Some(mode_indicator) = handle.upgrade(cx) {
18 // match event {
19 // VimEvent::ModeChanged { mode } => {
20 // mode_indicator.window().update(cx, |cx| {
21 // mode_indicator.update(cx, move |mode_indicator, cx| {
22 // mode_indicator.set_mode(mode, cx);
23 // })
24 // });
25 // }
26 // }
27 // }
28 // });
29
30 cx.observe_global::<SettingsStore>(move |mode_indicator, cx| {
31 if VimModeSetting::get_global(cx).0 {
32 mode_indicator.mode = cx
33 .has_global::<Vim>()
34 .then(|| cx.global::<Vim>().state().mode);
35 } else {
36 mode_indicator.mode.take();
37 }
38 })
39 .detach();
40
41 // Vim doesn't exist in some tests
42 let mode = cx
43 .has_global::<Vim>()
44 .then(|| {
45 let vim = cx.global::<Vim>();
46 vim.enabled.then(|| vim.state().mode)
47 })
48 .flatten();
49
50 Self {
51 mode,
52 // _subscription,
53 }
54 }
55
56 pub fn set_mode(&mut self, mode: Mode, cx: &mut ViewContext<Self>) {
57 if self.mode != Some(mode) {
58 self.mode = Some(mode);
59 cx.notify();
60 }
61 }
62}
63
64impl Render for ModeIndicator {
65 type Element = AnyElement;
66
67 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement {
68 let Some(mode) = self.mode.as_ref() else {
69 return div().into_any();
70 };
71
72 let text = match mode {
73 Mode::Normal => "-- NORMAL --",
74 Mode::Insert => "-- INSERT --",
75 Mode::Visual => "-- VISUAL --",
76 Mode::VisualLine => "-- VISUAL LINE --",
77 Mode::VisualBlock => "-- VISUAL BLOCK --",
78 };
79 Label::new(text).into_any_element()
80 }
81}
82
83impl StatusItemView for ModeIndicator {
84 fn set_active_pane_item(
85 &mut self,
86 _active_pane_item: Option<&dyn ItemHandle>,
87 _cx: &mut ViewContext<Self>,
88 ) {
89 // nothing to do.
90 }
91}