diff --git a/assets/settings/default.json b/assets/settings/default.json index f1071f9676..efb0cc9479 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -490,9 +490,6 @@ "version": "2", // Whether the assistant is enabled. "enabled": true, - // Whether to show inline hints showing the keybindings to use the inline assistant and the - // assistant panel. - "show_hints": false, // Whether to show the assistant panel button in the status bar. "button": true, // Where to dock the assistant panel. Can be 'left', 'right' or 'bottom'. diff --git a/crates/assistant/src/assistant_settings.rs b/crates/assistant/src/assistant_settings.rs index a782f05d03..87baf041ff 100644 --- a/crates/assistant/src/assistant_settings.rs +++ b/crates/assistant/src/assistant_settings.rs @@ -59,7 +59,6 @@ pub struct AssistantSettings { pub inline_alternatives: Vec, pub using_outdated_settings_version: bool, pub enable_experimental_live_diffs: bool, - pub show_hints: bool, } impl AssistantSettings { @@ -202,7 +201,6 @@ impl AssistantSettingsContent { AssistantSettingsContent::Versioned(settings) => match settings { VersionedAssistantSettingsContent::V1(settings) => AssistantSettingsContentV2 { enabled: settings.enabled, - show_hints: None, button: settings.button, dock: settings.dock, default_width: settings.default_width, @@ -243,7 +241,6 @@ impl AssistantSettingsContent { }, AssistantSettingsContent::Legacy(settings) => AssistantSettingsContentV2 { enabled: None, - show_hints: None, button: settings.button, dock: settings.dock, default_width: settings.default_width, @@ -356,7 +353,6 @@ impl Default for VersionedAssistantSettingsContent { fn default() -> Self { Self::V2(AssistantSettingsContentV2 { enabled: None, - show_hints: None, button: None, dock: None, default_width: None, @@ -374,11 +370,6 @@ pub struct AssistantSettingsContentV2 { /// /// Default: true enabled: Option, - /// Whether to show inline hints that show keybindings for inline assistant - /// and assistant panel. - /// - /// Default: true - show_hints: Option, /// Whether to show the assistant panel button in the status bar. /// /// Default: true @@ -513,7 +504,6 @@ impl Settings for AssistantSettings { let value = value.upgrade(); merge(&mut settings.enabled, value.enabled); - merge(&mut settings.show_hints, value.show_hints); merge(&mut settings.button, value.button); merge(&mut settings.dock, value.dock); merge( @@ -584,7 +574,6 @@ mod tests { }), inline_alternatives: None, enabled: None, - show_hints: None, button: None, dock: None, default_width: None, diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 401462795e..78f0aab5a5 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -534,15 +534,6 @@ pub enum IsVimMode { No, } -pub trait ActiveLineTrailerProvider { - fn render_active_line_trailer( - &mut self, - style: &EditorStyle, - focus_handle: &FocusHandle, - cx: &mut WindowContext, - ) -> Option; -} - /// Zed's primary text input `View`, allowing users to edit a [`MultiBuffer`] /// /// See the [module level documentation](self) for more information. @@ -670,7 +661,6 @@ pub struct Editor { next_scroll_position: NextScrollCursorCenterTopBottom, addons: HashMap>, _scroll_cursor_center_top_bottom_task: Task<()>, - active_line_trailer_provider: Option>, } #[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] @@ -2209,7 +2199,6 @@ impl Editor { addons: HashMap::default(), _scroll_cursor_center_top_bottom_task: Task::ready(()), text_style_refinement: None, - active_line_trailer_provider: None, }; this.tasks_update_task = Some(this.refresh_runnables(cx)); this._subscriptions.extend(project_subscriptions); @@ -2498,16 +2487,6 @@ impl Editor { self.refresh_inline_completion(false, false, cx); } - pub fn set_active_line_trailer_provider( - &mut self, - provider: Option, - _cx: &mut ViewContext, - ) where - T: ActiveLineTrailerProvider + 'static, - { - self.active_line_trailer_provider = provider.map(|provider| Box::new(provider) as Box<_>); - } - pub fn placeholder_text(&self, _cx: &WindowContext) -> Option<&str> { self.placeholder_text.as_deref() } @@ -11891,29 +11870,6 @@ impl Editor { && self.has_blame_entries(cx) } - pub fn render_active_line_trailer( - &mut self, - style: &EditorStyle, - cx: &mut WindowContext, - ) -> Option { - let selection = self.selections.newest::(cx); - if !selection.is_empty() { - return None; - }; - - let snapshot = self.buffer.read(cx).snapshot(cx); - let buffer_row = MultiBufferRow(selection.head().row); - - if snapshot.line_len(buffer_row) != 0 || self.has_active_inline_completion(cx) { - return None; - } - - let focus_handle = self.focus_handle.clone(); - self.active_line_trailer_provider - .as_mut()? - .render_active_line_trailer(style, &focus_handle, cx) - } - fn has_blame_entries(&self, cx: &mut WindowContext) -> bool { self.blame() .map_or(false, |blame| blame.read(cx).has_generated_entries()) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 0c403022a3..7f4bc3fb77 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -1414,7 +1414,7 @@ impl EditorElement { } #[allow(clippy::too_many_arguments)] - fn layout_active_line_trailer( + fn layout_inline_blame( &self, display_row: DisplayRow, display_snapshot: &DisplaySnapshot, @@ -1426,71 +1426,61 @@ impl EditorElement { line_height: Pixels, cx: &mut WindowContext, ) -> Option { - let render_inline_blame = self + if !self .editor - .update(cx, |editor, cx| editor.render_git_blame_inline(cx)); - if render_inline_blame { - let workspace = self - .editor - .read(cx) - .workspace - .as_ref() - .map(|(w, _)| w.clone()); - - let display_point = DisplayPoint::new(display_row, 0); - let buffer_row = MultiBufferRow(display_point.to_point(display_snapshot).row); - - let blame = self.editor.read(cx).blame.clone()?; - let blame_entry = blame - .update(cx, |blame, cx| { - blame.blame_for_rows([Some(buffer_row)], cx).next() - }) - .flatten()?; - - let mut element = - render_inline_blame_entry(&blame, blame_entry, &self.style, workspace, cx); - - let start_y = content_origin.y - + line_height * (display_row.as_f32() - scroll_pixel_position.y / line_height); - - let start_x = { - const INLINE_BLAME_PADDING_EM_WIDTHS: f32 = 6.; - - let line_end = if let Some(crease_trailer) = crease_trailer { - crease_trailer.bounds.right() - } else { - content_origin.x - scroll_pixel_position.x + line_layout.width - }; - let padded_line_end = line_end + em_width * INLINE_BLAME_PADDING_EM_WIDTHS; - - let min_column_in_pixels = ProjectSettings::get_global(cx) - .git - .inline_blame - .and_then(|settings| settings.min_column) - .map(|col| self.column_pixels(col as usize, cx)) - .unwrap_or(px(0.)); - let min_start = content_origin.x - scroll_pixel_position.x + min_column_in_pixels; - - cmp::max(padded_line_end, min_start) - }; - - let absolute_offset = point(start_x, start_y); - element.prepaint_as_root(absolute_offset, AvailableSpace::min_size(), cx); - - Some(element) - } else if let Some(mut element) = self.editor.update(cx, |editor, cx| { - editor.render_active_line_trailer(&self.style, cx) - }) { - let start_y = content_origin.y - + line_height * (display_row.as_f32() - scroll_pixel_position.y / line_height); - let start_x = content_origin.x - scroll_pixel_position.x + em_width; - let absolute_offset = point(start_x, start_y); - element.prepaint_as_root(absolute_offset, AvailableSpace::min_size(), cx); - - Some(element) - } else { - None + .update(cx, |editor, cx| editor.render_git_blame_inline(cx)) + { + return None; } + + let workspace = self + .editor + .read(cx) + .workspace + .as_ref() + .map(|(w, _)| w.clone()); + + let display_point = DisplayPoint::new(display_row, 0); + let buffer_row = MultiBufferRow(display_point.to_point(display_snapshot).row); + + let blame = self.editor.read(cx).blame.clone()?; + let blame_entry = blame + .update(cx, |blame, cx| { + blame.blame_for_rows([Some(buffer_row)], cx).next() + }) + .flatten()?; + + let mut element = + render_inline_blame_entry(&blame, blame_entry, &self.style, workspace, cx); + + let start_y = content_origin.y + + line_height * (display_row.as_f32() - scroll_pixel_position.y / line_height); + + let start_x = { + const INLINE_BLAME_PADDING_EM_WIDTHS: f32 = 6.; + + let line_end = if let Some(crease_trailer) = crease_trailer { + crease_trailer.bounds.right() + } else { + content_origin.x - scroll_pixel_position.x + line_layout.width + }; + let padded_line_end = line_end + em_width * INLINE_BLAME_PADDING_EM_WIDTHS; + + let min_column_in_pixels = ProjectSettings::get_global(cx) + .git + .inline_blame + .and_then(|settings| settings.min_column) + .map(|col| self.column_pixels(col as usize, cx)) + .unwrap_or(px(0.)); + let min_start = content_origin.x - scroll_pixel_position.x + min_column_in_pixels; + + cmp::max(padded_line_end, min_start) + }; + + let absolute_offset = point(start_x, start_y); + element.prepaint_as_root(absolute_offset, AvailableSpace::min_size(), cx); + + Some(element) } #[allow(clippy::too_many_arguments)] @@ -3466,7 +3456,7 @@ impl EditorElement { self.paint_lines(&invisible_display_ranges, layout, cx); self.paint_redactions(layout, cx); self.paint_cursors(layout, cx); - self.paint_active_line_trailer(layout, cx); + self.paint_inline_blame(layout, cx); cx.with_element_namespace("crease_trailers", |cx| { for trailer in layout.crease_trailers.iter_mut().flatten() { trailer.element.paint(cx); @@ -3948,10 +3938,10 @@ impl EditorElement { } } - fn paint_active_line_trailer(&mut self, layout: &mut EditorLayout, cx: &mut WindowContext) { - if let Some(mut element) = layout.active_line_trailer.take() { + fn paint_inline_blame(&mut self, layout: &mut EditorLayout, cx: &mut WindowContext) { + if let Some(mut inline_blame) = layout.inline_blame.take() { cx.paint_layer(layout.text_hitbox.bounds, |cx| { - element.paint(cx); + inline_blame.paint(cx); }) } } @@ -5343,14 +5333,14 @@ impl Element for EditorElement { ) }); - let mut active_line_trailer = None; + let mut inline_blame = None; if let Some(newest_selection_head) = newest_selection_head { let display_row = newest_selection_head.row(); if (start_row..end_row).contains(&display_row) { let line_ix = display_row.minus(start_row) as usize; let line_layout = &line_layouts[line_ix]; let crease_trailer_layout = crease_trailers[line_ix].as_ref(); - active_line_trailer = self.layout_active_line_trailer( + inline_blame = self.layout_inline_blame( display_row, &snapshot.display_snapshot, line_layout, @@ -5669,7 +5659,7 @@ impl Element for EditorElement { line_elements, line_numbers, blamed_display_rows, - active_line_trailer, + inline_blame, blocks, cursors, visible_cursors, @@ -5806,7 +5796,7 @@ pub struct EditorLayout { line_numbers: Vec>, display_hunks: Vec<(DisplayDiffHunk, Option)>, blamed_display_rows: Option>, - active_line_trailer: Option, + inline_blame: Option, blocks: Vec, highlighted_ranges: Vec<(Range, Hsla)>, highlighted_gutter_ranges: Vec<(Range, Hsla)>, diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index 2b6f1d4a99..c1c14edba2 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -3064,7 +3064,7 @@ impl<'a> WindowContext<'a> { } /// Represent this action as a key binding string, to display in the UI. - pub fn keystroke_text_for_action(&self, action: &dyn Action) -> String { + pub fn keystroke_text_for(&self, action: &dyn Action) -> String { self.bindings_for_action(action) .into_iter() .next() @@ -3079,26 +3079,6 @@ impl<'a> WindowContext<'a> { .unwrap_or_else(|| action.name().to_string()) } - /// Represent this action as a key binding string, to display in the UI. - pub fn keystroke_text_for_action_in( - &self, - action: &dyn Action, - focus_handle: &FocusHandle, - ) -> String { - self.bindings_for_action_in(action, focus_handle) - .into_iter() - .next() - .map(|binding| { - binding - .keystrokes() - .iter() - .map(ToString::to_string) - .collect::>() - .join(" ") - }) - .unwrap_or_else(|| action.name().to_string()) - } - /// Dispatch a mouse or keyboard event on the window. #[profiling::function] pub fn dispatch_event(&mut self, event: PlatformInput) -> DispatchEventResult { diff --git a/crates/outline_panel/src/outline_panel.rs b/crates/outline_panel/src/outline_panel.rs index f378348782..f878b582d9 100644 --- a/crates/outline_panel/src/outline_panel.rs +++ b/crates/outline_panel/src/outline_panel.rs @@ -3875,13 +3875,13 @@ impl OutlinePanel { .child({ let keystroke = match self.position(cx) { DockPosition::Left => { - cx.keystroke_text_for_action(&workspace::ToggleLeftDock) + cx.keystroke_text_for(&workspace::ToggleLeftDock) } DockPosition::Bottom => { - cx.keystroke_text_for_action(&workspace::ToggleBottomDock) + cx.keystroke_text_for(&workspace::ToggleBottomDock) } DockPosition::Right => { - cx.keystroke_text_for_action(&workspace::ToggleRightDock) + cx.keystroke_text_for(&workspace::ToggleRightDock) } }; Label::new(format!("Toggle this panel with {keystroke}")) diff --git a/crates/recent_projects/src/recent_projects.rs b/crates/recent_projects/src/recent_projects.rs index c08136cdf5..404bf26b62 100644 --- a/crates/recent_projects/src/recent_projects.rs +++ b/crates/recent_projects/src/recent_projects.rs @@ -172,13 +172,13 @@ impl PickerDelegate for RecentProjectsDelegate { fn placeholder_text(&self, cx: &mut WindowContext) -> Arc { let (create_window, reuse_window) = if self.create_new_window { ( - cx.keystroke_text_for_action(&menu::Confirm), - cx.keystroke_text_for_action(&menu::SecondaryConfirm), + cx.keystroke_text_for(&menu::Confirm), + cx.keystroke_text_for(&menu::SecondaryConfirm), ) } else { ( - cx.keystroke_text_for_action(&menu::SecondaryConfirm), - cx.keystroke_text_for_action(&menu::Confirm), + cx.keystroke_text_for(&menu::SecondaryConfirm), + cx.keystroke_text_for(&menu::Confirm), ) }; Arc::from(format!( diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 6febe05d10..cccd50da96 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -61,7 +61,7 @@ use zed::{ OpenRequest, }; -use crate::zed::{assistant_hints, inline_completion_registry}; +use crate::zed::inline_completion_registry; #[cfg(feature = "mimalloc")] #[global_allocator] @@ -407,7 +407,6 @@ fn main() { cx, ); assistant2::init(cx); - assistant_hints::init(cx); repl::init( app_state.fs.clone(), app_state.client.telemetry().clone(), diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index be6df49a2d..5ba63b9c1f 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -1,5 +1,4 @@ mod app_menus; -pub mod assistant_hints; pub mod inline_completion_registry; #[cfg(any(target_os = "linux", target_os = "freebsd"))] pub(crate) mod linux_prompts; diff --git a/crates/zed/src/zed/assistant_hints.rs b/crates/zed/src/zed/assistant_hints.rs deleted file mode 100644 index 244b7fab26..0000000000 --- a/crates/zed/src/zed/assistant_hints.rs +++ /dev/null @@ -1,115 +0,0 @@ -use assistant::assistant_settings::AssistantSettings; -use collections::HashMap; -use editor::{ActiveLineTrailerProvider, Editor, EditorMode}; -use gpui::{AnyWindowHandle, AppContext, ViewContext, WeakView, WindowContext}; -use settings::{Settings, SettingsStore}; -use std::{cell::RefCell, rc::Rc}; -use theme::ActiveTheme; -use ui::prelude::*; -use workspace::Workspace; - -pub fn init(cx: &mut AppContext) { - let editors: Rc, AnyWindowHandle>>> = Rc::default(); - - cx.observe_new_views({ - let editors = editors.clone(); - move |_: &mut Workspace, cx: &mut ViewContext| { - let workspace_handle = cx.view().clone(); - cx.subscribe(&workspace_handle, { - let editors = editors.clone(); - move |_, _, event, cx| match event { - workspace::Event::ItemAdded { item } => { - if let Some(editor) = item.act_as::(cx) { - if editor.read(cx).mode() != EditorMode::Full { - return; - } - - cx.on_release({ - let editor_handle = editor.downgrade(); - let editors = editors.clone(); - move |_, _, _| { - editors.borrow_mut().remove(&editor_handle); - } - }) - .detach(); - editors - .borrow_mut() - .insert(editor.downgrade(), cx.window_handle()); - - let show_hints = should_show_hints(cx); - editor.update(cx, |editor, cx| { - assign_active_line_trailer_provider(editor, show_hints, cx) - }) - } - } - _ => {} - } - }) - .detach(); - } - }) - .detach(); - - let mut show_hints = AssistantSettings::get_global(cx).show_hints; - cx.observe_global::(move |cx| { - let new_show_hints = should_show_hints(cx); - if new_show_hints != show_hints { - show_hints = new_show_hints; - for (editor, window) in editors.borrow().iter() { - _ = window.update(cx, |_window, cx| { - _ = editor.update(cx, |editor, cx| { - assign_active_line_trailer_provider(editor, show_hints, cx); - }) - }); - } - } - }) - .detach(); -} - -struct AssistantHintsProvider; - -impl ActiveLineTrailerProvider for AssistantHintsProvider { - fn render_active_line_trailer( - &mut self, - style: &editor::EditorStyle, - focus_handle: &gpui::FocusHandle, - cx: &mut WindowContext, - ) -> Option { - if !focus_handle.is_focused(cx) { - return None; - } - - let chat_keybinding = - cx.keystroke_text_for_action_in(&assistant::ToggleFocus, focus_handle); - let generate_keybinding = - cx.keystroke_text_for_action_in(&zed_actions::InlineAssist::default(), focus_handle); - - Some( - h_flex() - .id("inline-assistant-instructions") - .w_full() - .font_family(style.text.font().family) - .text_color(cx.theme().status().hint) - .line_height(style.text.line_height) - .child(format!( - "{chat_keybinding} to chat, {generate_keybinding} to generate" - )) - .into_any(), - ) - } -} - -fn assign_active_line_trailer_provider( - editor: &mut Editor, - show_hints: bool, - cx: &mut ViewContext, -) { - let provider = show_hints.then_some(AssistantHintsProvider); - editor.set_active_line_trailer_provider(provider, cx); -} - -fn should_show_hints(cx: &AppContext) -> bool { - let assistant_settings = AssistantSettings::get_global(cx); - assistant_settings.enabled && assistant_settings.show_hints -} diff --git a/docs/src/assistant/configuration.md b/docs/src/assistant/configuration.md index 1be96491f4..2145bd9504 100644 --- a/docs/src/assistant/configuration.md +++ b/docs/src/assistant/configuration.md @@ -200,28 +200,18 @@ You must provide the model's Context Window in the `max_tokens` parameter, this { "assistant": { "enabled": true, - "show_hints": true, - "button": true, - "dock": "right" - "default_width": 480, "default_model": { "provider": "zed.dev", "model": "claude-3-5-sonnet" }, "version": "2", + "button": true, + "default_width": 480, + "dock": "right" } } ``` -| key | type | default | description | -| -------------- | ------- | ------- | ------------------------------------------------------------------------------------- | -| enabled | boolean | true | Setting this to `false` will completely disable the assistant | -| show_hints | boolean | true | Whether to to show hints in the editor explaining how to use assistant | -| button | boolean | true | Show the assistant icon in the status bar | -| dock | string | "right" | The default dock position for the assistant panel. Can be ["left", "right", "bottom"] | -| default_height | string | null | The pixel height of the assistant panel when docked to the bottom | -| default_width | string | null | The pixel width of the assistant panel when docked to the left or right | - #### Custom endpoints {#custom-endpoint} You can use a custom API endpoint for different providers, as long as it's compatible with the providers API structure. @@ -281,3 +271,13 @@ will generate two outputs for every assist. One with Claude 3.5 Sonnet, and one } } ``` + +#### Common Panel Settings + +| key | type | default | description | +| -------------- | ------- | ------- | ------------------------------------------------------------------------------------- | +| enabled | boolean | true | Setting this to `false` will completely disable the assistant | +| button | boolean | true | Show the assistant icon in the status bar | +| dock | string | "right" | The default dock position for the assistant panel. Can be ["left", "right", "bottom"] | +| default_height | string | null | The pixel height of the assistant panel when docked to the bottom | +| default_width | string | null | The pixel width of the assistant panel when docked to the left or right | diff --git a/docs/src/configuring-zed.md b/docs/src/configuring-zed.md index 4991ff1119..5eacf4136d 100644 --- a/docs/src/configuring-zed.md +++ b/docs/src/configuring-zed.md @@ -2333,18 +2333,15 @@ Run the `theme selector: toggle` action in the command palette to see a current - Default: ```json -{ - "assistant": { - "enabled": true, - "button": true, - "dock": "right", - "default_width": 640, - "default_height": 320, - "provider": "openai", - "version": "1", - "show_hints": true - } -} +"assistant": { + "enabled": true, + "button": true, + "dock": "right", + "default_width": 640, + "default_height": 320, + "provider": "openai", + "version": "1", +}, ``` ## Outline Panel