active_buffer_language.rs

 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>) -> Element<Self> {
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, 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            })
68            .with_cursor_style(CursorStyle::PointingHand)
69            .on_click(MouseButton::Left, |_, _, cx| {
70                cx.dispatch_action(crate::Toggle)
71            })
72            .into_element()
73        } else {
74            Empty::new().into_element()
75        }
76    }
77}
78
79impl StatusItemView for ActiveBufferLanguage {
80    fn set_active_pane_item(
81        &mut self,
82        active_pane_item: Option<&dyn ItemHandle>,
83        cx: &mut ViewContext<Self>,
84    ) {
85        if let Some(editor) = active_pane_item.and_then(|item| item.act_as::<Editor>(cx)) {
86            self._observe_active_editor = Some(cx.observe(&editor, Self::update_language));
87            self.update_language(editor, cx);
88        } else {
89            self.active_language = None;
90            self._observe_active_editor = None;
91        }
92
93        cx.notify();
94    }
95}