Merge pull request #2263 from zed-industries/language-status-bar

Language status bar
This commit is contained in:
Mikayla Maki
2023-03-10 16:26:42 -08:00
committed by GitHub
12 changed files with 183 additions and 35 deletions
+1
View File
@@ -29,6 +29,7 @@ clock = { path = "../clock" }
collections = { path = "../collections" }
context_menu = { path = "../context_menu" }
editor = { path = "../editor" }
feedback = { path = "../feedback" }
fuzzy = { path = "../fuzzy" }
gpui = { path = "../gpui" }
menu = { path = "../menu" }
+14 -4
View File
@@ -304,12 +304,22 @@ impl CollabTitlebarItem {
label: "Sign out".into(),
action: Box::new(SignOut),
},
ContextMenuItem::Item {
label: "Give Feedback".into(),
action: Box::new(feedback::feedback_editor::GiveFeedback),
},
]
} else {
vec![ContextMenuItem::Item {
label: "Sign in".into(),
action: Box::new(Authenticate),
}]
vec![
ContextMenuItem::Item {
label: "Sign in".into(),
action: Box::new(Authenticate),
},
ContextMenuItem::Item {
label: "Give Feedback".into(),
action: Box::new(feedback::feedback_editor::GiveFeedback),
},
]
};
user_menu.show(
+15 -12
View File
@@ -1082,18 +1082,21 @@ impl MultiBuffer {
let mut cursor = snapshot.excerpts.cursor::<usize>();
cursor.seek(&position, Bias::Right, &());
cursor.item().map(|excerpt| {
(
excerpt.id.clone(),
self.buffers
.borrow()
.get(&excerpt.buffer_id)
.unwrap()
.buffer
.clone(),
excerpt.range.context.clone(),
)
})
cursor
.item()
.or_else(|| snapshot.excerpts.last())
.map(|excerpt| {
(
excerpt.id.clone(),
self.buffers
.borrow()
.get(&excerpt.buffer_id)
.unwrap()
.buffer
.clone(),
excerpt.range.context.clone(),
)
})
}
// If point is at the end of the buffer, the last excerpt is returned
+45 -10
View File
@@ -1,34 +1,59 @@
use gpui::{
elements::{MouseEventHandler, ParentElement, Stack, Text},
CursorStyle, Element, ElementBox, Entity, MouseButton, RenderContext, View, ViewContext,
};
use gpui::{elements::*, CursorStyle, Entity, MouseButton, RenderContext, View, ViewContext};
use settings::Settings;
use workspace::{item::ItemHandle, StatusItemView};
use crate::feedback_editor::GiveFeedback;
use crate::feedback_editor::{FeedbackEditor, GiveFeedback};
pub struct DeployFeedbackButton;
pub struct DeployFeedbackButton {
active: bool,
}
impl Entity for DeployFeedbackButton {
type Event = ();
}
impl DeployFeedbackButton {
pub fn new() -> Self {
DeployFeedbackButton { active: false }
}
}
impl View for DeployFeedbackButton {
fn ui_name() -> &'static str {
"DeployFeedbackButton"
}
fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox {
let active = self.active;
Stack::new()
.with_child(
MouseEventHandler::<Self>::new(0, cx, |state, cx| {
let theme = &cx.global::<Settings>().theme;
let theme = &theme.workspace.status_bar.feedback;
let style = &theme
.workspace
.status_bar
.sidebar_buttons
.item
.style_for(state, active);
Text::new("Give Feedback", theme.style_for(state, true).clone()).boxed()
Svg::new("icons/speech_bubble_12.svg")
.with_color(style.icon_color)
.constrained()
.with_width(style.icon_size)
.aligned()
.constrained()
.with_width(style.icon_size)
.with_height(style.icon_size)
.contained()
.with_style(style.container)
.boxed()
})
.with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, |_, cx| cx.dispatch_action(GiveFeedback))
.on_click(MouseButton::Left, move |_, cx| {
if !active {
cx.dispatch_action(GiveFeedback)
}
})
.boxed(),
)
.boxed()
@@ -36,5 +61,15 @@ impl View for DeployFeedbackButton {
}
impl StatusItemView for DeployFeedbackButton {
fn set_active_pane_item(&mut self, _: Option<&dyn ItemHandle>, _: &mut ViewContext<Self>) {}
fn set_active_pane_item(&mut self, item: Option<&dyn ItemHandle>, cx: &mut ViewContext<Self>) {
if let Some(item) = item {
if let Some(_) = item.downcast::<FeedbackEditor>() {
self.active = true;
cx.notify();
return;
}
}
self.active = false;
cx.notify();
}
}
@@ -0,0 +1,87 @@
use editor::Editor;
use gpui::{
elements::*, CursorStyle, Entity, MouseButton, RenderContext, Subscription, View, ViewContext,
ViewHandle,
};
use settings::Settings;
use std::sync::Arc;
use workspace::{item::ItemHandle, StatusItemView};
pub struct ActiveBufferLanguage {
active_language: Option<Arc<str>>,
_observe_active_editor: Option<Subscription>,
}
impl Default for ActiveBufferLanguage {
fn default() -> Self {
Self::new()
}
}
impl ActiveBufferLanguage {
pub fn new() -> Self {
Self {
active_language: None,
_observe_active_editor: None,
}
}
fn update_language(&mut self, editor: ViewHandle<Editor>, cx: &mut ViewContext<Self>) {
self.active_language.take();
let editor = editor.read(cx);
if let Some((_, buffer, _)) = editor.active_excerpt(cx) {
if let Some(language) = buffer.read(cx).language() {
self.active_language = Some(language.name());
}
}
cx.notify();
}
}
impl Entity for ActiveBufferLanguage {
type Event = ();
}
impl View for ActiveBufferLanguage {
fn ui_name() -> &'static str {
"ActiveBufferLanguage"
}
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
if let Some(active_language) = self.active_language.as_ref() {
MouseEventHandler::<Self>::new(0, cx, |state, cx| {
let theme = &cx.global::<Settings>().theme.workspace.status_bar;
let style = theme.active_language.style_for(state, false);
Label::new(active_language.to_string(), style.text.clone())
.contained()
.with_style(style.container)
.boxed()
})
.with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, |_, cx| cx.dispatch_action(crate::Toggle))
.boxed()
} else {
Empty::new().boxed()
}
}
}
impl StatusItemView for ActiveBufferLanguage {
fn set_active_pane_item(
&mut self,
active_pane_item: Option<&dyn ItemHandle>,
cx: &mut ViewContext<Self>,
) {
if let Some(editor) = active_pane_item.and_then(|item| item.act_as::<Editor>(cx)) {
self._observe_active_editor = Some(cx.observe(&editor, Self::update_language));
self.update_language(editor, cx);
} else {
self.active_language = None;
self._observe_active_editor = None;
}
cx.notify();
}
}
@@ -1,5 +1,6 @@
use std::sync::Arc;
mod active_buffer_language;
pub use active_buffer_language::ActiveBufferLanguage;
use editor::Editor;
use fuzzy::{match_strings, StringMatch, StringMatchCandidate};
use gpui::{
@@ -10,6 +11,7 @@ use language::{Buffer, LanguageRegistry};
use picker::{Picker, PickerDelegate};
use project::Project;
use settings::Settings;
use std::sync::Arc;
use workspace::{AppState, Workspace};
actions!(language_selector, [Toggle]);
+1 -1
View File
@@ -292,10 +292,10 @@ pub struct StatusBar {
pub height: f32,
pub item_spacing: f32,
pub cursor_position: TextStyle,
pub active_language: Interactive<ContainedText>,
pub auto_update_progress_message: TextStyle,
pub auto_update_done_message: TextStyle,
pub lsp_status: Interactive<StatusBarLspStatus>,
pub feedback: Interactive<TextStyle>,
pub sidebar_buttons: StatusBarSidebarButtons,
pub diagnostic_summary: Interactive<StatusBarDiagnosticSummary>,
pub diagnostic_message: Interactive<ContainedText>,
+1
View File
@@ -141,6 +141,7 @@ pub fn menus() -> Vec<Menu<'static>> {
MenuItem::action("View Dependency Licenses", crate::OpenLicenses),
MenuItem::action("Show Welcome", workspace::Welcome),
MenuItem::separator(),
MenuItem::action("Give us feedback", feedback::feedback_editor::GiveFeedback),
MenuItem::action(
"Copy System Specs Into Clipboard",
feedback::CopySystemSpecsIntoClipboard,
+5 -3
View File
@@ -340,14 +340,16 @@ pub fn initialize_workspace(
cx.add_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace.project(), cx));
let activity_indicator =
activity_indicator::ActivityIndicator::new(workspace, app_state.languages.clone(), cx);
let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new());
let active_buffer_language = cx.add_view(|_| language_selector::ActiveBufferLanguage::new());
let feedback_button =
cx.add_view(|_| feedback::deploy_feedback_button::DeployFeedbackButton {});
cx.add_view(|_| feedback::deploy_feedback_button::DeployFeedbackButton::new());
let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new());
workspace.status_bar().update(cx, |status_bar, cx| {
status_bar.add_left_item(diagnostic_summary, cx);
status_bar.add_left_item(activity_indicator, cx);
status_bar.add_right_item(cursor_position, cx);
status_bar.add_right_item(feedback_button, cx);
status_bar.add_right_item(active_buffer_language, cx);
status_bar.add_right_item(cursor_position, cx);
});
auto_update::notify_of_any_new_update(cx.weak_handle(), cx);