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