Skip to content

Commit

Permalink
Editor toolbar configuration (#7338)
Browse files Browse the repository at this point in the history
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](#4756))
  • Loading branch information
alygin authored Feb 3, 2024
1 parent 55185c1 commit 8da6e62
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 39 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions assets/settings/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@
// Share your project when you are the first to join a channel
"share_on_join": true
},
// Toolbar related settings
"toolbar": {
// Whether to show breadcrumbs.
"breadcrumbs": true,
// Whether to show quick action buttons.
"quick_actions": true
},
// Scrollbar related settings
"scrollbar": {
// When to show the scrollbar in the editor.
Expand Down
7 changes: 5 additions & 2 deletions crates/editor/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ pub struct Editor {
hovered_cursors: HashMap<HoveredCursor, Task<()>>,
pub show_local_selections: bool,
mode: EditorMode,
show_breadcrumbs: bool,
show_gutter: bool,
show_wrap_guides: Option<bool>,
placeholder_text: Option<Arc<str>>,
Expand Down Expand Up @@ -1448,6 +1449,7 @@ impl Editor {
blink_manager: blink_manager.clone(),
show_local_selections: true,
mode,
show_breadcrumbs: EditorSettings::get_global(cx).toolbar.breadcrumbs,
show_gutter: mode == EditorMode::Full,
show_wrap_guides: None,
placeholder_text: None,
Expand Down Expand Up @@ -8762,8 +8764,9 @@ impl Editor {
)),
cx,
);
self.scroll_manager.vertical_scroll_margin =
EditorSettings::get_global(cx).vertical_scroll_margin;
let editor_settings = EditorSettings::get_global(cx);
self.scroll_manager.vertical_scroll_margin = editor_settings.vertical_scroll_margin;
self.show_breadcrumbs = editor_settings.toolbar.breadcrumbs;
cx.notify();
}

Expand Down
22 changes: 22 additions & 0 deletions crates/editor/src/editor_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub struct EditorSettings {
pub show_completion_documentation: bool,
pub completion_documentation_secondary_query_debounce: u64,
pub use_on_type_format: bool,
pub toolbar: Toolbar,
pub scrollbar: Scrollbar,
pub vertical_scroll_margin: f32,
pub relative_line_numbers: bool,
Expand All @@ -29,6 +30,12 @@ pub enum SeedQuerySetting {
Never,
}

#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
pub struct Toolbar {
pub breadcrumbs: bool,
pub quick_actions: bool,
}

#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
pub struct Scrollbar {
pub show: ShowScrollbar,
Expand Down Expand Up @@ -86,6 +93,8 @@ pub struct EditorSettingsContent {
///
/// Default: true
pub use_on_type_format: Option<bool>,
/// Toolbar related settings
pub toolbar: Option<ToolbarContent>,
/// Scrollbar related settings
pub scrollbar: Option<ScrollbarContent>,

Expand All @@ -110,6 +119,19 @@ pub struct EditorSettingsContent {
pub redact_private_values: Option<bool>,
}

// Toolbar related settings
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
pub struct ToolbarContent {
/// Whether to display breadcrumbs in the editor toolbar.
///
/// Default: true
pub breadcrumbs: Option<bool>,
/// Whether to display quik action buttons in the editor toolbar.
///
/// Default: true
pub quick_actions: Option<bool>,
}

/// Scrollbar related settings
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
pub struct ScrollbarContent {
Expand Down
6 changes: 5 additions & 1 deletion crates/editor/src/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,11 @@ impl Item for Editor {
}

fn breadcrumb_location(&self) -> ToolbarItemLocation {
ToolbarItemLocation::PrimaryLeft
if self.show_breadcrumbs {
ToolbarItemLocation::PrimaryLeft
} else {
ToolbarItemLocation::Hidden
}
}

fn breadcrumbs(&self, variant: &Theme, cx: &AppContext) -> Option<Vec<BreadcrumbText>> {
Expand Down
1 change: 1 addition & 0 deletions crates/quick_action_bar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ assistant = { path = "../assistant" }
editor = { path = "../editor" }
gpui = { path = "../gpui" }
search = { path = "../search" }
settings = { path = "../settings" }
ui = { path = "../ui" }
workspace = { path = "../workspace" }

Expand Down
88 changes: 54 additions & 34 deletions crates/quick_action_bar/src/quick_action_bar.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -16,31 +17,58 @@ 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>> {
self.active_item
.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 {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
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,
Expand Down Expand Up @@ -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();

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
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()
}
}));
}
}
self.get_toolbar_item_location()
}
}
2 changes: 1 addition & 1 deletion crates/workspace/src/toolbar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ impl Render for Toolbar {
h_flex()
// We're using `flex_none` here to prevent some flickering that can occur when the
// size of the left items container changes.
.flex_none()
.when_else(has_left_items, Div::flex_none, Div::flex_auto)
.justify_end()
.children(self.right_items().map(|item| item.to_any())),
)
Expand Down
2 changes: 1 addition & 1 deletion crates/zed/src/zed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ fn initialize_pane(workspace: &mut Workspace, pane: &View<Pane>, cx: &mut ViewCo
toolbar.add_item(buffer_search_bar.clone(), cx);

let quick_action_bar =
cx.new_view(|_| QuickActionBar::new(buffer_search_bar, workspace));
cx.new_view(|cx| QuickActionBar::new(buffer_search_bar, workspace, cx));
toolbar.add_item(quick_action_bar, cx);
let diagnostic_editor_controls = cx.new_view(|_| diagnostics::ToolbarControls::new());
toolbar.add_item(diagnostic_editor_controls, cx);
Expand Down
17 changes: 17 additions & 0 deletions docs/src/configuring_zed.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,23 @@ List of `string` values
2. Position the dock to the right of the workspace like a side panel: `right`
3. Position the dock full screen over the entire workspace: `expanded`

## Editor Toolbar

- Description: Whether or not to show various elements in the editor toolbar.
- Setting: `toolbar`
- Default:

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

**Options**

Each option controls displaying of a particular toolbar element. If all elements are hidden, the editor toolbar is not displayed.

## Enable Language Server

- Description: Whether or not to use language servers to provide code intelligence.
Expand Down

0 comments on commit 8da6e62

Please sign in to comment.