line_ending_indicator.rs

 1use editor::Editor;
 2use gpui::{Entity, Subscription, WeakEntity};
 3use language::LineEnding;
 4use ui::{Tooltip, prelude::*};
 5use workspace::{StatusBarSettings, StatusItemView, item::ItemHandle, item::Settings};
 6
 7use crate::{LineEndingSelector, Toggle};
 8
 9#[derive(Default)]
10pub struct LineEndingIndicator {
11    line_ending: Option<LineEnding>,
12    active_editor: Option<WeakEntity<Editor>>,
13    _observe_active_editor: Option<Subscription>,
14}
15
16impl LineEndingIndicator {
17    fn update(&mut self, editor: Entity<Editor>, _: &mut Window, cx: &mut Context<Self>) {
18        self.line_ending = None;
19        self.active_editor = None;
20
21        if let Some((_, buffer, _)) = editor.read(cx).active_excerpt(cx) {
22            let line_ending = buffer.read(cx).line_ending();
23            self.line_ending = Some(line_ending);
24            self.active_editor = Some(editor.downgrade());
25        }
26
27        cx.notify();
28    }
29}
30
31impl Render for LineEndingIndicator {
32    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
33        if !StatusBarSettings::get_global(cx).line_endings_button {
34            return div();
35        }
36
37        div().when_some(self.line_ending.as_ref(), |el, line_ending| {
38            el.child(
39                Button::new("change-line-ending", line_ending.label())
40                    .label_size(LabelSize::Small)
41                    .on_click(cx.listener(|this, _, window, cx| {
42                        if let Some(editor) = this.active_editor.as_ref() {
43                            LineEndingSelector::toggle(editor, window, cx);
44                        }
45                    }))
46                    .tooltip(|window, cx| {
47                        Tooltip::for_action("Select Line Ending", &Toggle, window, cx)
48                    }),
49            )
50        })
51    }
52}
53
54impl StatusItemView for LineEndingIndicator {
55    fn set_active_pane_item(
56        &mut self,
57        active_pane_item: Option<&dyn ItemHandle>,
58        window: &mut Window,
59        cx: &mut Context<Self>,
60    ) {
61        if let Some(editor) = active_pane_item.and_then(|item| item.downcast::<Editor>()) {
62            self._observe_active_editor = Some(cx.observe_in(&editor, window, Self::update));
63            self.update(editor, window, cx);
64        } else {
65            self.line_ending = None;
66            self._observe_active_editor = None;
67        }
68        cx.notify();
69    }
70}