Editor toolbar configuration (#7338)

Adds settings for hiding breadcrumbs and quick action bar from
the editor toolbar. If both elements are hidden, the toolbar disappears
completely.

Example:

```json
"toolbar": {
  "breadcrumbs": true,
  "quick_actions": false
}
```

- It intentionally doesn't hide breadcrumbs in other views (for
instance, in the search result window) because their usage there differ
from the main editor.
- The editor controls how breadcrumbs are displayed in the toolbar, so
implementation differs a bit for breadcrumbs and quick actions bar.

Release Notes:

- Added support for configuring the editor toolbar ([4756](https://github.com/zed-industries/zed/issues/4756))
This commit is contained in:
Andrew Lygin 2024-02-03 23:40:54 +03:00 committed by GitHub
parent 55185c159b
commit 8da6e62914
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 113 additions and 38 deletions

View file

@ -1,11 +1,12 @@
use assistant::{AssistantPanel, InlineAssist};
use editor::Editor;
use editor::{Editor, EditorSettings};
use gpui::{
Action, ClickEvent, ElementId, EventEmitter, InteractiveElement, ParentElement, Render, Styled,
Subscription, View, ViewContext, WeakView,
};
use search::{buffer_search, BufferSearchBar};
use settings::{Settings, SettingsStore};
use ui::{prelude::*, ButtonSize, ButtonStyle, IconButton, IconName, IconSize, Tooltip};
use workspace::{
item::ItemHandle, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace,
@ -16,16 +17,26 @@ pub struct QuickActionBar {
active_item: Option<Box<dyn ItemHandle>>,
_inlay_hints_enabled_subscription: Option<Subscription>,
workspace: WeakView<Workspace>,
show: bool,
}
impl QuickActionBar {
pub fn new(buffer_search_bar: View<BufferSearchBar>, workspace: &Workspace) -> Self {
Self {
pub fn new(
buffer_search_bar: View<BufferSearchBar>,
workspace: &Workspace,
cx: &mut ViewContext<Self>,
) -> Self {
let mut this = Self {
buffer_search_bar,
active_item: None,
_inlay_hints_enabled_subscription: None,
workspace: workspace.weak_handle(),
}
show: true,
};
this.apply_settings(cx);
cx.observe_global::<SettingsStore>(|this, cx| this.apply_settings(cx))
.detach();
this
}
fn active_editor(&self) -> Option<View<Editor>> {
@ -33,6 +44,24 @@ impl QuickActionBar {
.as_ref()
.and_then(|item| item.downcast::<Editor>())
}
fn apply_settings(&mut self, cx: &mut ViewContext<Self>) {
let new_show = EditorSettings::get_global(cx).toolbar.quick_actions;
if new_show != self.show {
self.show = new_show;
cx.emit(ToolbarItemEvent::ChangeLocation(
self.get_toolbar_item_location(),
));
}
}
fn get_toolbar_item_location(&self) -> ToolbarItemLocation {
if self.show && self.active_editor().is_some() {
ToolbarItemLocation::PrimaryRight
} else {
ToolbarItemLocation::Hidden
}
}
}
impl Render for QuickActionBar {
@ -40,7 +69,6 @@ impl Render for QuickActionBar {
let Some(editor) = self.active_editor() else {
return div().id("empty quick action bar");
};
let inlay_hints_button = Some(QuickActionBarButton::new(
"toggle inlay hints",
IconName::InlayHint,
@ -155,36 +183,28 @@ impl ToolbarItemView for QuickActionBar {
active_pane_item: Option<&dyn ItemHandle>,
cx: &mut ViewContext<Self>,
) -> ToolbarItemLocation {
match active_pane_item {
Some(active_item) => {
self.active_item = Some(active_item.boxed_clone());
self._inlay_hints_enabled_subscription.take();
self.active_item = active_pane_item.map(ItemHandle::boxed_clone);
if let Some(active_item) = active_pane_item {
self._inlay_hints_enabled_subscription.take();
if let Some(editor) = active_item.downcast::<Editor>() {
let mut inlay_hints_enabled = editor.read(cx).inlay_hints_enabled();
let mut supports_inlay_hints = editor.read(cx).supports_inlay_hints(cx);
self._inlay_hints_enabled_subscription =
Some(cx.observe(&editor, move |_, editor, cx| {
let editor = editor.read(cx);
let new_inlay_hints_enabled = editor.inlay_hints_enabled();
let new_supports_inlay_hints = editor.supports_inlay_hints(cx);
let should_notify = inlay_hints_enabled != new_inlay_hints_enabled
|| supports_inlay_hints != new_supports_inlay_hints;
inlay_hints_enabled = new_inlay_hints_enabled;
supports_inlay_hints = new_supports_inlay_hints;
if should_notify {
cx.notify()
}
}));
ToolbarItemLocation::PrimaryRight
} else {
ToolbarItemLocation::Hidden
}
}
None => {
self.active_item = None;
ToolbarItemLocation::Hidden
if let Some(editor) = active_item.downcast::<Editor>() {
let mut inlay_hints_enabled = editor.read(cx).inlay_hints_enabled();
let mut supports_inlay_hints = editor.read(cx).supports_inlay_hints(cx);
self._inlay_hints_enabled_subscription =
Some(cx.observe(&editor, move |_, editor, cx| {
let editor = editor.read(cx);
let new_inlay_hints_enabled = editor.inlay_hints_enabled();
let new_supports_inlay_hints = editor.supports_inlay_hints(cx);
let should_notify = inlay_hints_enabled != new_inlay_hints_enabled
|| supports_inlay_hints != new_supports_inlay_hints;
inlay_hints_enabled = new_inlay_hints_enabled;
supports_inlay_hints = new_supports_inlay_hints;
if should_notify {
cx.notify()
}
}));
}
}
self.get_toolbar_item_location()
}
}