active_buffer_language.rs

 1use editor::Editor;
 2use gpui::{
 3    elements::*,
 4    platform::{CursorStyle, MouseButton},
 5    Entity, RenderContext, 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 RenderContext<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}