edit predictions: Add binding to the prediction toggle (#24468)
This PR primary goal is to add a keybinding to the (ephemeral) prediction toggle. In doing that, we also standardized the keybinding to open the status bar menu with it. Release Notes: - N/A --------- Co-authored-by: Bennet Bo Fenner <53836821+bennetbo@users.noreply.github.com>
This commit is contained in:
parent
07f1b612cf
commit
c4bcff1e87
7 changed files with 215 additions and 162 deletions
6
assets/icons/lock_outlined.svg
Normal file
6
assets/icons/lock_outlined.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5 5C5 3.89543 5.89543 3 7 3H9C10.1046 3 11 3.89543 11 5V6H5V5Z" stroke="black" stroke-width="1.5"/>
|
||||
<path d="M8 9V11" stroke="black" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<circle cx="8" cy="9" r="1" fill="black"/>
|
||||
<rect x="3.75" y="5.75" width="8.5" height="7.5" rx="1.25" stroke="black" stroke-width="1.5" stroke-linejoin="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 452 B |
|
@ -122,7 +122,8 @@
|
|||
"ctrl-i": "editor::ShowSignatureHelp",
|
||||
"alt-g b": "editor::ToggleGitBlame",
|
||||
"menu": "editor::OpenContextMenu",
|
||||
"shift-f10": "editor::OpenContextMenu"
|
||||
"shift-f10": "editor::OpenContextMenu",
|
||||
"ctrl-shift-e": "editor::ToggleEditPrediction"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -535,8 +536,7 @@
|
|||
{
|
||||
"bindings": {
|
||||
"ctrl-alt-shift-f": "workspace::FollowNextCollaborator",
|
||||
"ctrl-alt-i": "zed::DebugElements",
|
||||
"ctrl-:": "editor::ToggleInlayHints"
|
||||
"ctrl-alt-i": "zed::DebugElements"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -554,7 +554,8 @@
|
|||
"ctrl-shift-e": "pane::RevealInProjectPanel",
|
||||
"ctrl-f8": "editor::GoToHunk",
|
||||
"ctrl-shift-f8": "editor::GoToPrevHunk",
|
||||
"ctrl-enter": "assistant::InlineAssist"
|
||||
"ctrl-enter": "assistant::InlineAssist",
|
||||
"ctrl-:": "editor::ToggleInlayHints"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -39,8 +39,8 @@
|
|||
"cmd-m": "zed::Minimize",
|
||||
"fn-f": "zed::ToggleFullScreen",
|
||||
"ctrl-cmd-f": "zed::ToggleFullScreen",
|
||||
"ctrl-shift-z": "zeta::RateCompletions",
|
||||
"ctrl-shift-i": "edit_prediction::ToggleMenu"
|
||||
"ctrl-cmd-z": "zeta::RateCompletions",
|
||||
"ctrl-cmd-i": "edit_prediction::ToggleMenu"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -132,7 +132,8 @@
|
|||
"cmd-alt-g b": "editor::ToggleGitBlame",
|
||||
"cmd-i": "editor::ShowSignatureHelp",
|
||||
"ctrl-f12": "editor::GoToDeclaration",
|
||||
"alt-ctrl-f12": "editor::GoToDeclarationSplit"
|
||||
"alt-ctrl-f12": "editor::GoToDeclarationSplit",
|
||||
"ctrl-cmd-e": "editor::ToggleEditPrediction"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -619,8 +620,7 @@
|
|||
"ctrl-alt-cmd-f": "workspace::FollowNextCollaborator",
|
||||
// TODO: Move this to a dock open action
|
||||
"cmd-shift-c": "collab_panel::ToggleFocus",
|
||||
"cmd-alt-i": "zed::DebugElements",
|
||||
"ctrl-:": "editor::ToggleInlayHints"
|
||||
"cmd-alt-i": "zed::DebugElements"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -633,7 +633,8 @@
|
|||
"cmd-shift-e": "pane::RevealInProjectPanel",
|
||||
"cmd-f8": "editor::GoToHunk",
|
||||
"cmd-shift-f8": "editor::GoToPrevHunk",
|
||||
"ctrl-enter": "assistant::InlineAssist"
|
||||
"ctrl-enter": "assistant::InlineAssist",
|
||||
"ctrl-:": "editor::ToggleInlayHints"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
use anyhow::Result;
|
||||
use client::UserStore;
|
||||
use copilot::{Copilot, Status};
|
||||
use editor::{actions::ShowEditPrediction, scroll::Autoscroll, Editor};
|
||||
use editor::{
|
||||
actions::{ShowEditPrediction, ToggleEditPrediction},
|
||||
scroll::Autoscroll,
|
||||
Editor,
|
||||
};
|
||||
use feature_flags::{
|
||||
FeatureFlagAppExt, PredictEditsFeatureFlag, PredictEditsRateCompletionsFeatureFlag,
|
||||
};
|
||||
|
@ -44,6 +48,7 @@ struct CopilotErrorToast;
|
|||
pub struct InlineCompletionButton {
|
||||
editor_subscription: Option<(Subscription, usize)>,
|
||||
editor_enabled: Option<bool>,
|
||||
editor_show_predictions: bool,
|
||||
editor_focus_handle: Option<FocusHandle>,
|
||||
language: Option<Arc<Language>>,
|
||||
file: Option<Arc<dyn File>>,
|
||||
|
@ -275,15 +280,29 @@ impl Render for InlineCompletionButton {
|
|||
);
|
||||
}
|
||||
|
||||
let show_editor_predictions = self.editor_show_predictions;
|
||||
|
||||
let icon_button = IconButton::new("zed-predict-pending-button", zeta_icon)
|
||||
.shape(IconButtonShape::Square)
|
||||
.when(enabled && !show_editor_predictions, |this| {
|
||||
this.indicator(Indicator::dot().color(Color::Muted))
|
||||
.indicator_border_color(Some(cx.theme().colors().status_bar_background))
|
||||
})
|
||||
.when(!self.popover_menu_handle.is_deployed(), |element| {
|
||||
if enabled {
|
||||
element.tooltip(|window, cx| {
|
||||
Tooltip::for_action("Edit Prediction", &ToggleMenu, window, cx)
|
||||
})
|
||||
} else {
|
||||
element.tooltip(|window, cx| {
|
||||
element.tooltip(move |window, cx| {
|
||||
if enabled {
|
||||
if show_editor_predictions {
|
||||
Tooltip::for_action("Edit Prediction", &ToggleMenu, window, cx)
|
||||
} else {
|
||||
Tooltip::with_meta(
|
||||
"Edit Prediction",
|
||||
Some(&ToggleMenu),
|
||||
"Hidden For This File",
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Tooltip::with_meta(
|
||||
"Edit Prediction",
|
||||
Some(&ToggleMenu),
|
||||
|
@ -291,8 +310,8 @@ impl Render for InlineCompletionButton {
|
|||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
let this = cx.entity().clone();
|
||||
|
@ -347,6 +366,7 @@ impl InlineCompletionButton {
|
|||
Self {
|
||||
editor_subscription: None,
|
||||
editor_enabled: None,
|
||||
editor_show_predictions: true,
|
||||
editor_focus_handle: None,
|
||||
language: None,
|
||||
file: None,
|
||||
|
@ -384,6 +404,21 @@ impl InlineCompletionButton {
|
|||
|
||||
menu = menu.header("Show Edit Predictions For");
|
||||
|
||||
if let Some(editor_focus_handle) = self.editor_focus_handle.clone() {
|
||||
menu = menu.toggleable_entry(
|
||||
"This File",
|
||||
self.editor_show_predictions,
|
||||
IconPosition::Start,
|
||||
Some(Box::new(ToggleEditPrediction)),
|
||||
{
|
||||
let editor_focus_handle = editor_focus_handle.clone();
|
||||
move |window, cx| {
|
||||
editor_focus_handle.dispatch_action(&ToggleEditPrediction, window, cx);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(language) = self.language.clone() {
|
||||
let fs = fs.clone();
|
||||
let language_enabled =
|
||||
|
@ -393,7 +428,7 @@ impl InlineCompletionButton {
|
|||
menu = menu.toggleable_entry(
|
||||
language.name(),
|
||||
language_enabled,
|
||||
IconPosition::End,
|
||||
IconPosition::Start,
|
||||
None,
|
||||
move |_, cx| {
|
||||
toggle_show_inline_completions_for_language(language.clone(), fs.clone(), cx)
|
||||
|
@ -406,7 +441,7 @@ impl InlineCompletionButton {
|
|||
menu = menu.toggleable_entry(
|
||||
"All Files",
|
||||
globally_enabled,
|
||||
IconPosition::End,
|
||||
IconPosition::Start,
|
||||
None,
|
||||
move |_, cx| toggle_inline_completions_globally(fs.clone(), cx),
|
||||
);
|
||||
|
@ -422,7 +457,7 @@ impl InlineCompletionButton {
|
|||
// TODO: We want to add something later that communicates whether
|
||||
// the current project is open-source.
|
||||
ContextMenuEntry::new("Share Training Data")
|
||||
.toggleable(IconPosition::End, data_collection.is_enabled())
|
||||
.toggleable(IconPosition::Start, data_collection.is_enabled())
|
||||
.documentation_aside(|_| {
|
||||
Label::new(indoc!{"
|
||||
Help us improve our open model by sharing data from open source repositories. \
|
||||
|
@ -450,6 +485,8 @@ impl InlineCompletionButton {
|
|||
|
||||
menu = menu.item(
|
||||
ContextMenuEntry::new("Configure Excluded Files")
|
||||
.icon(IconName::LockOutlined)
|
||||
.icon_color(Color::Muted)
|
||||
.documentation_aside(|_| {
|
||||
Label::new(indoc!{"
|
||||
Open your settings to add sensitive paths for which Zed will never predict edits."}).into_any_element()
|
||||
|
@ -486,7 +523,6 @@ impl InlineCompletionButton {
|
|||
Some(Box::new(ShowEditPrediction)),
|
||||
{
|
||||
let editor_focus_handle = editor_focus_handle.clone();
|
||||
|
||||
move |window, cx| {
|
||||
editor_focus_handle.dispatch_action(&ShowEditPrediction, window, cx);
|
||||
}
|
||||
|
@ -571,6 +607,7 @@ impl InlineCompletionButton {
|
|||
.unwrap_or(true),
|
||||
)
|
||||
};
|
||||
self.editor_show_predictions = editor.should_show_inline_completions(cx);
|
||||
self.edit_prediction_provider = editor.edit_prediction_provider();
|
||||
self.language = language.cloned();
|
||||
self.file = file;
|
||||
|
|
|
@ -674,7 +674,8 @@ impl Render for ContextMenu {
|
|||
let contents = if toggled {
|
||||
v_flex().flex_none().child(
|
||||
Icon::new(IconName::Check)
|
||||
.color(Color::Accent),
|
||||
.color(Color::Accent)
|
||||
.size(*icon_size)
|
||||
)
|
||||
} else {
|
||||
v_flex().flex_none().size(
|
||||
|
|
|
@ -234,6 +234,7 @@ pub enum IconName {
|
|||
Link,
|
||||
ListTree,
|
||||
ListX,
|
||||
LockOutlined,
|
||||
MagnifyingGlass,
|
||||
MailOpen,
|
||||
Maximize,
|
||||
|
|
|
@ -213,6 +213,7 @@ impl Render for QuickActionBar {
|
|||
})
|
||||
});
|
||||
|
||||
let editor_focus_handle = editor.focus_handle(cx);
|
||||
let editor = editor.downgrade();
|
||||
let editor_settings_dropdown = {
|
||||
let vim_mode_enabled = VimModeSetting::get_global(cx).0;
|
||||
|
@ -231,20 +232,67 @@ impl Render for QuickActionBar {
|
|||
.anchor(Corner::TopRight)
|
||||
.with_handle(self.toggle_settings_handle.clone())
|
||||
.menu(move |window, cx| {
|
||||
let menu = ContextMenu::build(window, cx, |mut menu, _, _| {
|
||||
if supports_inlay_hints {
|
||||
let menu = ContextMenu::build(window, cx, {
|
||||
let focus_handle = editor_focus_handle.clone();
|
||||
|mut menu, _, _| {
|
||||
menu = menu.context(focus_handle);
|
||||
|
||||
if supports_inlay_hints {
|
||||
menu = menu.toggleable_entry(
|
||||
"Inlay Hints",
|
||||
inlay_hints_enabled,
|
||||
IconPosition::Start,
|
||||
Some(editor::actions::ToggleInlayHints.boxed_clone()),
|
||||
{
|
||||
let editor = editor.clone();
|
||||
move |window, cx| {
|
||||
editor
|
||||
.update(cx, |editor, cx| {
|
||||
editor.toggle_inlay_hints(
|
||||
&editor::actions::ToggleInlayHints,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
menu = menu.toggleable_entry(
|
||||
"Inlay Hints",
|
||||
inlay_hints_enabled,
|
||||
"Selection Menu",
|
||||
selection_menu_enabled,
|
||||
IconPosition::Start,
|
||||
Some(editor::actions::ToggleInlayHints.boxed_clone()),
|
||||
Some(editor::actions::ToggleSelectionMenu.boxed_clone()),
|
||||
{
|
||||
let editor = editor.clone();
|
||||
move |window, cx| {
|
||||
editor
|
||||
.update(cx, |editor, cx| {
|
||||
editor.toggle_inlay_hints(
|
||||
&editor::actions::ToggleInlayHints,
|
||||
editor.toggle_selection_menu(
|
||||
&editor::actions::ToggleSelectionMenu,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
menu = menu.toggleable_entry(
|
||||
"Auto Signature Help",
|
||||
auto_signature_help_enabled,
|
||||
IconPosition::Start,
|
||||
Some(editor::actions::ToggleAutoSignatureHelp.boxed_clone()),
|
||||
{
|
||||
let editor = editor.clone();
|
||||
move |window, cx| {
|
||||
editor
|
||||
.update(cx, |editor, cx| {
|
||||
editor.toggle_auto_signature_help_menu(
|
||||
&editor::actions::ToggleAutoSignatureHelp,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
|
@ -253,138 +301,96 @@ impl Render for QuickActionBar {
|
|||
}
|
||||
},
|
||||
);
|
||||
|
||||
let mut inline_completion_entry = ContextMenuEntry::new("Edit Predictions")
|
||||
.toggleable(IconPosition::Start, inline_completion_enabled && show_inline_completions)
|
||||
.disabled(!inline_completion_enabled)
|
||||
.action(Some(
|
||||
editor::actions::ToggleEditPrediction.boxed_clone(),
|
||||
)).handler({
|
||||
let editor = editor.clone();
|
||||
move |window, cx| {
|
||||
editor
|
||||
.update(cx, |editor, cx| {
|
||||
editor.toggle_inline_completions(
|
||||
&editor::actions::ToggleEditPrediction,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
});
|
||||
if !inline_completion_enabled {
|
||||
inline_completion_entry = inline_completion_entry.documentation_aside(|_| {
|
||||
Label::new("You can't toggle edit predictions for this file as it is within the excluded files list.").into_any_element()
|
||||
});
|
||||
}
|
||||
|
||||
menu = menu.item(inline_completion_entry);
|
||||
|
||||
menu = menu.separator();
|
||||
|
||||
menu = menu.toggleable_entry(
|
||||
"Inline Git Blame",
|
||||
git_blame_inline_enabled,
|
||||
IconPosition::Start,
|
||||
Some(editor::actions::ToggleGitBlameInline.boxed_clone()),
|
||||
{
|
||||
let editor = editor.clone();
|
||||
move |window, cx| {
|
||||
editor
|
||||
.update(cx, |editor, cx| {
|
||||
editor.toggle_git_blame_inline(
|
||||
&editor::actions::ToggleGitBlameInline,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
menu = menu.toggleable_entry(
|
||||
"Column Git Blame",
|
||||
show_git_blame_gutter,
|
||||
IconPosition::Start,
|
||||
Some(editor::actions::ToggleGitBlame.boxed_clone()),
|
||||
{
|
||||
let editor = editor.clone();
|
||||
move |window, cx| {
|
||||
editor
|
||||
.update(cx, |editor, cx| {
|
||||
editor.toggle_git_blame(
|
||||
&editor::actions::ToggleGitBlame,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
menu = menu.separator();
|
||||
|
||||
menu = menu.toggleable_entry(
|
||||
"Vim Mode",
|
||||
vim_mode_enabled,
|
||||
IconPosition::Start,
|
||||
None,
|
||||
{
|
||||
move |window, cx| {
|
||||
let new_value = !vim_mode_enabled;
|
||||
VimModeSetting::override_global(VimModeSetting(new_value), cx);
|
||||
window.refresh();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
menu
|
||||
}
|
||||
|
||||
menu = menu.toggleable_entry(
|
||||
"Selection Menu",
|
||||
selection_menu_enabled,
|
||||
IconPosition::Start,
|
||||
Some(editor::actions::ToggleSelectionMenu.boxed_clone()),
|
||||
{
|
||||
let editor = editor.clone();
|
||||
move |window, cx| {
|
||||
editor
|
||||
.update(cx, |editor, cx| {
|
||||
editor.toggle_selection_menu(
|
||||
&editor::actions::ToggleSelectionMenu,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
menu = menu.toggleable_entry(
|
||||
"Auto Signature Help",
|
||||
auto_signature_help_enabled,
|
||||
IconPosition::Start,
|
||||
Some(editor::actions::ToggleAutoSignatureHelp.boxed_clone()),
|
||||
{
|
||||
let editor = editor.clone();
|
||||
move |window, cx| {
|
||||
editor
|
||||
.update(cx, |editor, cx| {
|
||||
editor.toggle_auto_signature_help_menu(
|
||||
&editor::actions::ToggleAutoSignatureHelp,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
let mut inline_completion_entry = ContextMenuEntry::new("Edit Predictions")
|
||||
.toggleable(IconPosition::Start, inline_completion_enabled && show_inline_completions)
|
||||
.disabled(!inline_completion_enabled)
|
||||
.action(Some(
|
||||
editor::actions::ToggleEditPrediction.boxed_clone(),
|
||||
)).handler({
|
||||
let editor = editor.clone();
|
||||
move |window, cx| {
|
||||
editor
|
||||
.update(cx, |editor, cx| {
|
||||
editor.toggle_inline_completions(
|
||||
&editor::actions::ToggleEditPrediction,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
});
|
||||
if !inline_completion_enabled {
|
||||
inline_completion_entry = inline_completion_entry.documentation_aside(|_| {
|
||||
Label::new("You can't toggle edit predictions for this file as it is within the excluded files list.").into_any_element()
|
||||
});
|
||||
}
|
||||
|
||||
menu = menu.item(inline_completion_entry);
|
||||
|
||||
menu = menu.separator();
|
||||
|
||||
menu = menu.toggleable_entry(
|
||||
"Inline Git Blame",
|
||||
git_blame_inline_enabled,
|
||||
IconPosition::Start,
|
||||
Some(editor::actions::ToggleGitBlameInline.boxed_clone()),
|
||||
{
|
||||
let editor = editor.clone();
|
||||
move |window, cx| {
|
||||
editor
|
||||
.update(cx, |editor, cx| {
|
||||
editor.toggle_git_blame_inline(
|
||||
&editor::actions::ToggleGitBlameInline,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
menu = menu.toggleable_entry(
|
||||
"Column Git Blame",
|
||||
show_git_blame_gutter,
|
||||
IconPosition::Start,
|
||||
Some(editor::actions::ToggleGitBlame.boxed_clone()),
|
||||
{
|
||||
let editor = editor.clone();
|
||||
move |window, cx| {
|
||||
editor
|
||||
.update(cx, |editor, cx| {
|
||||
editor.toggle_git_blame(
|
||||
&editor::actions::ToggleGitBlame,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
menu = menu.separator();
|
||||
|
||||
menu = menu.toggleable_entry(
|
||||
"Vim Mode",
|
||||
vim_mode_enabled,
|
||||
IconPosition::Start,
|
||||
None,
|
||||
{
|
||||
move |window, cx| {
|
||||
let new_value = !vim_mode_enabled;
|
||||
VimModeSetting::override_global(VimModeSetting(new_value), cx);
|
||||
window.refresh();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
menu
|
||||
});
|
||||
Some(menu)
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue