Revise "Hide/Show Inline Completions" menu (#23808)

> **Note:** https://github.com/zed-industries/zed/pull/23813 should be
merged first!

@nathansobo and I paired on revising this menu, including adding the
"Predict Edits at Cursor" menu item (to make the keyboard shortcut more
discoverable; clicking it makes the inline edits show up, as shown in
the second screenshot) and switching from "Hide/Show" language to
checkboxes.

## Before
<img width="282" alt="Screenshot 2025-01-28 at 4 51 37 PM"
src="https://github.com/user-attachments/assets/309c82c1-8fb5-44db-950e-1a8789a63993"
/>

## After
<img width="1138" alt="Screenshot 2025-01-28 at 4 50 05 PM"
src="https://github.com/user-attachments/assets/302a126c-9389-42a4-bb7d-2896bce859e7"
/>

We also switched to use `SharedString` in more places, where it made
more sense.

@danilo-leal This isn't necessarily *exactly* what we want, but we were
pairing and decided to get it in a state where we can actually try it
out and tweak from here.

Release Notes:

- N/A

---------

Co-authored-by: Nathan <nathan@zed.dev>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: Marshall Bowers <git@maxdeviant.com>
This commit is contained in:
Richard Feldman 2025-01-29 15:45:28 -05:00 committed by GitHub
parent 4cef772364
commit ee0d2a8d94
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 52 additions and 24 deletions

View file

@ -1,14 +1,15 @@
use anyhow::Result;
use client::UserStore;
use copilot::{Copilot, Status};
use editor::{scroll::Autoscroll, Editor};
use editor::{actions::ShowInlineCompletion, scroll::Autoscroll, Editor};
use feature_flags::{
FeatureFlagAppExt, PredictEditsFeatureFlag, PredictEditsRateCompletionsFeatureFlag,
};
use fs::Fs;
use gpui::{
actions, div, pulsating_between, Action, Animation, AnimationExt, App, AsyncWindowContext,
Corner, Entity, IntoElement, ParentElement, Render, Subscription, WeakEntity,
Corner, Entity, FocusHandle, Focusable, IntoElement, ParentElement, Render, Subscription,
WeakEntity,
};
use language::{
language_settings::{
@ -43,6 +44,7 @@ struct CopilotErrorToast;
pub struct InlineCompletionButton {
editor_subscription: Option<(Subscription, usize)>,
editor_enabled: Option<bool>,
editor_focus_handle: Option<FocusHandle>,
language: Option<Arc<Language>>,
file: Option<Arc<dyn File>>,
inline_completion_provider: Option<Arc<dyn inline_completion::InlineCompletionProviderHandle>>,
@ -329,6 +331,7 @@ impl InlineCompletionButton {
Self {
editor_subscription: None,
editor_enabled: None,
editor_focus_handle: None,
language: None,
file: None,
inline_completion_provider: None,
@ -364,21 +367,26 @@ impl InlineCompletionButton {
})
}
// Predict Edits at Cursor alt-tab
// Automatically Predict:
// ✓ PATH
// ✓ Rust
// ✓ All Files
pub fn build_language_settings_menu(&self, mut menu: ContextMenu, cx: &mut App) -> ContextMenu {
let fs = self.fs.clone();
menu = menu.header("Predict Edits For:");
if let Some(language) = self.language.clone() {
let fs = fs.clone();
let language_enabled =
language_settings::language_settings(Some(language.name()), None, cx)
.show_inline_completions;
menu = menu.entry(
format!(
"{} Inline Completions for {}",
if language_enabled { "Hide" } else { "Show" },
language.name()
),
menu = menu.toggleable_entry(
language.name(),
language_enabled,
IconPosition::Start,
None,
move |_, cx| {
toggle_inline_completions_for_language(language.clone(), fs.clone(), cx)
@ -387,16 +395,14 @@ impl InlineCompletionButton {
}
let settings = AllLanguageSettings::get_global(cx);
if let Some(file) = &self.file {
let path = file.path().clone();
let path_enabled = settings.inline_completions_enabled_for_path(&path);
menu = menu.entry(
format!(
"{} Inline Completions for This Path",
if path_enabled { "Hide" } else { "Show" }
),
menu = menu.toggleable_entry(
"This File",
path_enabled,
IconPosition::Start,
None,
move |window, cx| {
if let Some(workspace) = window.root().flatten() {
@ -416,15 +422,32 @@ impl InlineCompletionButton {
}
let globally_enabled = settings.inline_completions_enabled(None, None, cx);
menu.entry(
if globally_enabled {
"Hide Inline Completions for All Files"
} else {
"Show Inline Completions for All Files"
},
menu = menu.toggleable_entry(
"All Files",
globally_enabled,
IconPosition::Start,
None,
move |_, cx| toggle_inline_completions_globally(fs.clone(), cx),
)
);
if let Some(editor_focus_handle) = self.editor_focus_handle.clone() {
menu = menu
.separator()
.entry(
"Predict Edit at Cursor",
Some(Box::new(ShowInlineCompletion)),
{
let editor_focus_handle = editor_focus_handle.clone();
move |window, cx| {
editor_focus_handle.dispatch_action(&ShowInlineCompletion, window, cx);
}
},
)
.context(editor_focus_handle);
}
menu
}
fn build_copilot_context_menu(
@ -468,7 +491,7 @@ impl InlineCompletionButton {
self.build_language_settings_menu(menu, cx).when(
cx.has_flag::<PredictEditsRateCompletionsFeatureFlag>(),
|this| {
this.separator().entry(
this.entry(
"Rate Completions",
Some(RateCompletions.boxed_clone()),
move |window, cx| {
@ -504,6 +527,7 @@ impl InlineCompletionButton {
self.inline_completion_provider = editor.inline_completion_provider();
self.language = language.cloned();
self.file = file;
self.editor_focus_handle = Some(editor.focus_handle(cx));
cx.notify();
}

View file

@ -49,7 +49,7 @@ impl RenderOnce for ListSubHeader {
.px(DynamicSpacing::Base02.rems(cx))
.child(
div()
.h_6()
.h_5()
.when(self.inset, |this| this.px_2())
.when(self.selected, |this| {
this.bg(cx.theme().colors().ghost_element_selected)
@ -70,7 +70,11 @@ impl RenderOnce for ListSubHeader {
Icon::new(i).color(Color::Muted).size(IconSize::Small)
}),
)
.child(Label::new(self.label.clone()).color(Color::Muted)),
.child(
Label::new(self.label.clone())
.color(Color::Muted)
.size(LabelSize::Small),
),
),
)
}