1use editor::Editor;
2use gpui::{
3 elements::*,
4 platform::{CursorStyle, MouseButton},
5 Entity, Subscription, View, ViewContext, ViewHandle,
6};
7use settings::Settings;
8use std::sync::Arc;
9use workspace::{item::ItemHandle, StatusItemView};
10
11pub struct ActiveBufferLanguage {
12 active_language: Option<Option<Arc<str>>>,
13 _observe_active_editor: Option<Subscription>,
14}
15
16impl Default for ActiveBufferLanguage {
17 fn default() -> Self {
18 Self::new()
19 }
20}
21
22impl ActiveBufferLanguage {
23 pub fn new() -> Self {
24 Self {
25 active_language: None,
26 _observe_active_editor: None,
27 }
28 }
29
30 fn update_language(&mut self, editor: ViewHandle<Editor>, cx: &mut ViewContext<Self>) {
31 self.active_language = Some(None);
32
33 let editor = editor.read(cx);
34 if let Some((_, buffer, _)) = editor.active_excerpt(cx) {
35 if let Some(language) = buffer.read(cx).language() {
36 self.active_language = Some(Some(language.name()));
37 }
38 }
39
40 cx.notify();
41 }
42}
43
44impl Entity for ActiveBufferLanguage {
45 type Event = ();
46}
47
48impl View for ActiveBufferLanguage {
49 fn ui_name() -> &'static str {
50 "ActiveBufferLanguage"
51 }
52
53 fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
54 if let Some(active_language) = self.active_language.as_ref() {
55 let active_language_text = if let Some(active_language_text) = active_language {
56 active_language_text.to_string()
57 } else {
58 "Unknown".to_string()
59 };
60
61 MouseEventHandler::<Self>::new(0, cx, |state, cx| {
62 let theme = &cx.global::<Settings>().theme.workspace.status_bar;
63 let style = theme.active_language.style_for(state, false);
64 Label::new(active_language_text, style.text.clone())
65 .contained()
66 .with_style(style.container)
67 .boxed()
68 })
69 .with_cursor_style(CursorStyle::PointingHand)
70 .on_click(MouseButton::Left, |_, cx| cx.dispatch_action(crate::Toggle))
71 .boxed()
72 } else {
73 Empty::new().boxed()
74 }
75 }
76}
77
78impl StatusItemView for ActiveBufferLanguage {
79 fn set_active_pane_item(
80 &mut self,
81 active_pane_item: Option<&dyn ItemHandle>,
82 cx: &mut ViewContext<Self>,
83 ) {
84 if let Some(editor) = active_pane_item.and_then(|item| item.act_as::<Editor>(cx)) {
85 self._observe_active_editor = Some(cx.observe(&editor, Self::update_language));
86 self.update_language(editor, cx);
87 } else {
88 self.active_language = None;
89 self._observe_active_editor = None;
90 }
91
92 cx.notify();
93 }
94}