active_buffer_language.rs

 1use editor::Editor;
 2use gpui::{div, IntoElement, ParentElement, Render, Subscription, View, ViewContext, WeakView};
 3use language::LanguageName;
 4use ui::{Button, ButtonCommon, Clickable, FluentBuilder, LabelSize, Tooltip};
 5use workspace::{item::ItemHandle, StatusItemView, Workspace};
 6
 7use crate::{LanguageSelector, Toggle};
 8
 9pub struct ActiveBufferLanguage {
10    active_language: Option<Option<LanguageName>>,
11    workspace: WeakView<Workspace>,
12    _observe_active_editor: Option<Subscription>,
13}
14
15impl ActiveBufferLanguage {
16    pub fn new(workspace: &Workspace) -> Self {
17        Self {
18            active_language: None,
19            workspace: workspace.weak_handle(),
20            _observe_active_editor: None,
21        }
22    }
23
24    fn update_language(&mut self, editor: View<Editor>, cx: &mut ViewContext<Self>) {
25        self.active_language = Some(None);
26
27        let editor = editor.read(cx);
28        if let Some((_, buffer, _)) = editor.active_excerpt(cx) {
29            if let Some(language) = buffer.read(cx).language() {
30                self.active_language = Some(Some(language.name()));
31            }
32        }
33
34        cx.notify();
35    }
36}
37
38impl Render for ActiveBufferLanguage {
39    fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
40        div().when_some(self.active_language.as_ref(), |el, active_language| {
41            let active_language_text = if let Some(active_language_text) = active_language {
42                active_language_text.to_string()
43            } else {
44                "Unknown".to_string()
45            };
46
47            el.child(
48                Button::new("change-language", active_language_text)
49                    .label_size(LabelSize::Small)
50                    .on_click(cx.listener(|this, _, cx| {
51                        if let Some(workspace) = this.workspace.upgrade() {
52                            workspace.update(cx, |workspace, cx| {
53                                LanguageSelector::toggle(workspace, cx)
54                            });
55                        }
56                    }))
57                    .tooltip(|cx| Tooltip::for_action("Select Language", &Toggle, cx)),
58            )
59        })
60    }
61}
62
63impl StatusItemView for ActiveBufferLanguage {
64    fn set_active_pane_item(
65        &mut self,
66        active_pane_item: Option<&dyn ItemHandle>,
67        cx: &mut ViewContext<Self>,
68    ) {
69        if let Some(editor) = active_pane_item.and_then(|item| item.downcast::<Editor>()) {
70            self._observe_active_editor = Some(cx.observe(&editor, Self::update_language));
71            self.update_language(editor, cx);
72        } else {
73            self.active_language = None;
74            self._observe_active_editor = None;
75        }
76
77        cx.notify();
78    }
79}