Detailed changes
@@ -210,6 +210,7 @@ dependencies = [
"chrono",
"client",
"collections",
+ "command_palette_hooks",
"component",
"context_server",
"db",
@@ -6360,6 +6361,7 @@ dependencies = [
"buffer_diff",
"call",
"chrono",
+ "client",
"collections",
"command_palette_hooks",
"component",
@@ -1076,6 +1076,10 @@
// Send anonymized usage data like what languages you're using Zed with.
"metrics": true
},
+ // Whether to disable all AI features in Zed.
+ //
+ // Default: false
+ "disable_ai": false,
// Automatically update Zed. This setting may be ignored on Linux if
// installed through a package manager.
"auto_update": true,
@@ -32,6 +32,7 @@ buffer_diff.workspace = true
chrono.workspace = true
client.workspace = true
collections.workspace = true
+command_palette_hooks.workspace = true
component.workspace = true
context_server.workspace = true
db.workspace = true
@@ -43,7 +43,7 @@ use anyhow::{Result, anyhow};
use assistant_context::{AssistantContext, ContextEvent, ContextSummary};
use assistant_slash_command::SlashCommandWorkingSet;
use assistant_tool::ToolWorkingSet;
-use client::{UserStore, zed_urls};
+use client::{DisableAiSettings, UserStore, zed_urls};
use editor::{Anchor, AnchorRangeExt as _, Editor, EditorEvent, MultiBuffer};
use feature_flags::{self, FeatureFlagAppExt};
use fs::Fs;
@@ -744,6 +744,7 @@ impl AgentPanel {
if workspace
.panel::<Self>(cx)
.is_some_and(|panel| panel.read(cx).enabled(cx))
+ && !DisableAiSettings::get_global(cx).disable_ai
{
workspace.toggle_panel_focus::<Self>(window, cx);
}
@@ -1665,7 +1666,10 @@ impl Panel for AgentPanel {
}
fn icon(&self, _window: &Window, cx: &App) -> Option<IconName> {
- (self.enabled(cx) && AgentSettings::get_global(cx).button).then_some(IconName::ZedAssistant)
+ (self.enabled(cx)
+ && AgentSettings::get_global(cx).button
+ && !DisableAiSettings::get_global(cx).disable_ai)
+ .then_some(IconName::ZedAssistant)
}
fn icon_tooltip(&self, _window: &Window, _cx: &App) -> Option<&'static str> {
@@ -31,7 +31,8 @@ use std::sync::Arc;
use agent::{Thread, ThreadId};
use agent_settings::{AgentProfileId, AgentSettings, LanguageModelSelection};
use assistant_slash_command::SlashCommandRegistry;
-use client::Client;
+use client::{Client, DisableAiSettings};
+use command_palette_hooks::CommandPaletteFilter;
use feature_flags::FeatureFlagAppExt as _;
use fs::Fs;
use gpui::{Action, App, Entity, actions};
@@ -43,6 +44,7 @@ use prompt_store::PromptBuilder;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings as _, SettingsStore};
+use std::any::TypeId;
pub use crate::active_thread::ActiveThread;
use crate::agent_configuration::{ConfigureContextServerModal, ManageProfilesModal};
@@ -52,6 +54,7 @@ use crate::slash_command_settings::SlashCommandSettings;
pub use agent_diff::{AgentDiffPane, AgentDiffToolbar};
pub use text_thread_editor::{AgentPanelDelegate, TextThreadEditor};
pub use ui::preview::{all_agent_previews, get_agent_preview};
+use zed_actions;
actions!(
agent,
@@ -241,6 +244,66 @@ pub fn init(
})
.detach();
cx.observe_new(ManageProfilesModal::register).detach();
+
+ // Update command palette filter based on AI settings
+ update_command_palette_filter(cx);
+
+ // Watch for settings changes
+ cx.observe_global::<SettingsStore>(|app_cx| {
+ // When settings change, update the command palette filter
+ update_command_palette_filter(app_cx);
+ })
+ .detach();
+}
+
+fn update_command_palette_filter(cx: &mut App) {
+ let disable_ai = DisableAiSettings::get_global(cx).disable_ai;
+ CommandPaletteFilter::update_global(cx, |filter, _| {
+ if disable_ai {
+ filter.hide_namespace("agent");
+ filter.hide_namespace("assistant");
+ filter.hide_namespace("zed_predict_onboarding");
+ filter.hide_namespace("edit_prediction");
+
+ use editor::actions::{
+ AcceptEditPrediction, AcceptPartialEditPrediction, NextEditPrediction,
+ PreviousEditPrediction, ShowEditPrediction, ToggleEditPrediction,
+ };
+ let edit_prediction_actions = [
+ TypeId::of::<AcceptEditPrediction>(),
+ TypeId::of::<AcceptPartialEditPrediction>(),
+ TypeId::of::<ShowEditPrediction>(),
+ TypeId::of::<NextEditPrediction>(),
+ TypeId::of::<PreviousEditPrediction>(),
+ TypeId::of::<ToggleEditPrediction>(),
+ ];
+ filter.hide_action_types(&edit_prediction_actions);
+ filter.hide_action_types(&[TypeId::of::<zed_actions::OpenZedPredictOnboarding>()]);
+ } else {
+ filter.show_namespace("agent");
+ filter.show_namespace("assistant");
+ filter.show_namespace("zed_predict_onboarding");
+
+ filter.show_namespace("edit_prediction");
+
+ use editor::actions::{
+ AcceptEditPrediction, AcceptPartialEditPrediction, NextEditPrediction,
+ PreviousEditPrediction, ShowEditPrediction, ToggleEditPrediction,
+ };
+ let edit_prediction_actions = [
+ TypeId::of::<AcceptEditPrediction>(),
+ TypeId::of::<AcceptPartialEditPrediction>(),
+ TypeId::of::<ShowEditPrediction>(),
+ TypeId::of::<NextEditPrediction>(),
+ TypeId::of::<PreviousEditPrediction>(),
+ TypeId::of::<ToggleEditPrediction>(),
+ ];
+ filter.show_action_types(edit_prediction_actions.iter());
+
+ filter
+ .show_action_types([TypeId::of::<zed_actions::OpenZedPredictOnboarding>()].iter());
+ }
+ });
}
fn init_language_model_settings(cx: &mut App) {
@@ -16,7 +16,7 @@ use agent::{
};
use agent_settings::AgentSettings;
use anyhow::{Context as _, Result};
-use client::telemetry::Telemetry;
+use client::{DisableAiSettings, telemetry::Telemetry};
use collections::{HashMap, HashSet, VecDeque, hash_map};
use editor::SelectionEffects;
use editor::{
@@ -57,6 +57,17 @@ pub fn init(
cx: &mut App,
) {
cx.set_global(InlineAssistant::new(fs, prompt_builder, telemetry));
+
+ cx.observe_global::<SettingsStore>(|cx| {
+ if DisableAiSettings::get_global(cx).disable_ai {
+ // Hide any active inline assist UI when AI is disabled
+ InlineAssistant::update_global(cx, |assistant, cx| {
+ assistant.cancel_all_active_completions(cx);
+ });
+ }
+ })
+ .detach();
+
cx.observe_new(|_workspace: &mut Workspace, window, cx| {
let Some(window) = window else {
return;
@@ -141,6 +152,26 @@ impl InlineAssistant {
.detach();
}
+ /// Hides all active inline assists when AI is disabled
+ pub fn cancel_all_active_completions(&mut self, cx: &mut App) {
+ // Cancel all active completions in editors
+ for (editor_handle, _) in self.assists_by_editor.iter() {
+ if let Some(editor) = editor_handle.upgrade() {
+ let windows = cx.windows();
+ if !windows.is_empty() {
+ let window = windows[0];
+ let _ = window.update(cx, |_, window, cx| {
+ editor.update(cx, |editor, cx| {
+ if editor.has_active_inline_completion() {
+ editor.cancel(&Default::default(), window, cx);
+ }
+ });
+ });
+ }
+ }
+ }
+ }
+
fn handle_workspace_event(
&mut self,
workspace: Entity<Workspace>,
@@ -176,7 +207,7 @@ impl InlineAssistant {
window: &mut Window,
cx: &mut App,
) {
- let is_assistant2_enabled = true;
+ let is_assistant2_enabled = !DisableAiSettings::get_global(cx).disable_ai;
if let Some(editor) = item.act_as::<Editor>(cx) {
editor.update(cx, |editor, cx| {
@@ -199,6 +230,13 @@ impl InlineAssistant {
cx,
);
+ if DisableAiSettings::get_global(cx).disable_ai {
+ // Cancel any active completions
+ if editor.has_active_inline_completion() {
+ editor.cancel(&Default::default(), window, cx);
+ }
+ }
+
// Remove the Assistant1 code action provider, as it still might be registered.
editor.remove_code_action_provider("assistant".into(), window, cx);
} else {
@@ -219,7 +257,7 @@ impl InlineAssistant {
cx: &mut Context<Workspace>,
) {
let settings = AgentSettings::get_global(cx);
- if !settings.enabled {
+ if !settings.enabled || DisableAiSettings::get_global(cx).disable_ai {
return;
}
@@ -20,6 +20,7 @@ anyhow.workspace = true
assistant_tool.workspace = true
buffer_diff.workspace = true
chrono.workspace = true
+client.workspace = true
collections.workspace = true
component.workspace = true
derive_more.workspace = true
@@ -20,14 +20,13 @@ mod thinking_tool;
mod ui;
mod web_search_tool;
-use std::sync::Arc;
-
use assistant_tool::ToolRegistry;
use copy_path_tool::CopyPathTool;
use gpui::{App, Entity};
use http_client::HttpClientWithUrl;
use language_model::LanguageModelRegistry;
use move_path_tool::MovePathTool;
+use std::sync::Arc;
use web_search_tool::WebSearchTool;
pub(crate) use templates::*;
@@ -151,6 +151,7 @@ impl Settings for ProxySettings {
pub fn init_settings(cx: &mut App) {
TelemetrySettings::register(cx);
+ DisableAiSettings::register(cx);
ClientSettings::register(cx);
ProxySettings::register(cx);
}
@@ -548,6 +549,33 @@ impl settings::Settings for TelemetrySettings {
}
}
+/// Whether to disable all AI features in Zed.
+///
+/// Default: false
+#[derive(Copy, Clone, Debug)]
+pub struct DisableAiSettings {
+ pub disable_ai: bool,
+}
+
+impl settings::Settings for DisableAiSettings {
+ const KEY: Option<&'static str> = Some("disable_ai");
+
+ type FileContent = Option<bool>;
+
+ fn load(sources: SettingsSources<Self::FileContent>, _: &mut App) -> Result<Self> {
+ Ok(Self {
+ disable_ai: sources
+ .user
+ .or(sources.server)
+ .copied()
+ .flatten()
+ .unwrap_or(sources.default.ok_or_else(Self::missing_default)?),
+ })
+ }
+
+ fn import_from_vscode(_vscode: &settings::VsCodeSettings, _current: &mut Self::FileContent) {}
+}
+
impl Client {
pub fn new(
clock: Arc<dyn SystemClock>,
@@ -6,6 +6,7 @@ mod sign_in;
use crate::sign_in::initiate_sign_in_within_workspace;
use ::fs::Fs;
use anyhow::{Context as _, Result, anyhow};
+use client::DisableAiSettings;
use collections::{HashMap, HashSet};
use command_palette_hooks::CommandPaletteFilter;
use futures::{Future, FutureExt, TryFutureExt, channel::oneshot, future::Shared};
@@ -25,6 +26,7 @@ use node_runtime::NodeRuntime;
use parking_lot::Mutex;
use request::StatusNotification;
use serde_json::json;
+use settings::Settings;
use settings::SettingsStore;
use sign_in::{reinstall_and_sign_in_within_workspace, sign_out_within_workspace};
use std::collections::hash_map::Entry;
@@ -93,26 +95,34 @@ pub fn init(
let copilot_auth_action_types = [TypeId::of::<SignOut>()];
let copilot_no_auth_action_types = [TypeId::of::<SignIn>()];
let status = handle.read(cx).status();
+
+ let is_ai_disabled = DisableAiSettings::get_global(cx).disable_ai;
let filter = CommandPaletteFilter::global_mut(cx);
- match status {
- Status::Disabled => {
- filter.hide_action_types(&copilot_action_types);
- filter.hide_action_types(&copilot_auth_action_types);
- filter.hide_action_types(&copilot_no_auth_action_types);
- }
- Status::Authorized => {
- filter.hide_action_types(&copilot_no_auth_action_types);
- filter.show_action_types(
- copilot_action_types
- .iter()
- .chain(&copilot_auth_action_types),
- );
- }
- _ => {
- filter.hide_action_types(&copilot_action_types);
- filter.hide_action_types(&copilot_auth_action_types);
- filter.show_action_types(copilot_no_auth_action_types.iter());
+ if is_ai_disabled {
+ filter.hide_action_types(&copilot_action_types);
+ filter.hide_action_types(&copilot_auth_action_types);
+ filter.hide_action_types(&copilot_no_auth_action_types);
+ } else {
+ match status {
+ Status::Disabled => {
+ filter.hide_action_types(&copilot_action_types);
+ filter.hide_action_types(&copilot_auth_action_types);
+ filter.hide_action_types(&copilot_no_auth_action_types);
+ }
+ Status::Authorized => {
+ filter.hide_action_types(&copilot_no_auth_action_types);
+ filter.show_action_types(
+ copilot_action_types
+ .iter()
+ .chain(&copilot_auth_action_types),
+ );
+ }
+ _ => {
+ filter.hide_action_types(&copilot_action_types);
+ filter.hide_action_types(&copilot_auth_action_types);
+ filter.show_action_types(copilot_no_auth_action_types.iter());
+ }
}
}
})
@@ -23,6 +23,7 @@ askpass.workspace = true
buffer_diff.workspace = true
call.workspace = true
chrono.workspace = true
+client.workspace = true
collections.workspace = true
command_palette_hooks.workspace = true
component.workspace = true
@@ -1,8 +1,10 @@
use crate::branch_picker::{self, BranchList};
use crate::git_panel::{GitPanel, commit_message_editor};
+use client::DisableAiSettings;
use git::repository::CommitOptions;
use git::{Amend, Commit, GenerateCommitMessage, Signoff};
use panel::{panel_button, panel_editor_style};
+use settings::Settings;
use ui::{
ContextMenu, KeybindingHint, PopoverMenu, PopoverMenuHandle, SplitButton, Tooltip, prelude::*,
};
@@ -569,11 +571,13 @@ impl Render for CommitModal {
.on_action(cx.listener(Self::dismiss))
.on_action(cx.listener(Self::commit))
.on_action(cx.listener(Self::amend))
- .on_action(cx.listener(|this, _: &GenerateCommitMessage, _, cx| {
- this.git_panel.update(cx, |panel, cx| {
- panel.generate_commit_message(cx);
- })
- }))
+ .when(!DisableAiSettings::get_global(cx).disable_ai, |this| {
+ this.on_action(cx.listener(|this, _: &GenerateCommitMessage, _, cx| {
+ this.git_panel.update(cx, |panel, cx| {
+ panel.generate_commit_message(cx);
+ })
+ }))
+ })
.on_action(
cx.listener(|this, _: &zed_actions::git::Branch, window, cx| {
this.toggle_branch_selector(window, cx);
@@ -12,6 +12,7 @@ use crate::{
use agent_settings::AgentSettings;
use anyhow::Context as _;
use askpass::AskPassDelegate;
+use client::DisableAiSettings;
use db::kvp::KEY_VALUE_STORE;
use editor::{
Editor, EditorElement, EditorMode, EditorSettings, MultiBuffer, ShowScrollbar,
@@ -53,7 +54,7 @@ use project::{
git_store::{GitStoreEvent, Repository},
};
use serde::{Deserialize, Serialize};
-use settings::{Settings as _, SettingsStore};
+use settings::{Settings, SettingsStore};
use std::future::Future;
use std::ops::Range;
use std::path::{Path, PathBuf};
@@ -464,9 +465,14 @@ impl GitPanel {
};
let mut assistant_enabled = AgentSettings::get_global(cx).enabled;
+ let mut was_ai_disabled = DisableAiSettings::get_global(cx).disable_ai;
let _settings_subscription = cx.observe_global::<SettingsStore>(move |_, cx| {
- if assistant_enabled != AgentSettings::get_global(cx).enabled {
+ let is_ai_disabled = DisableAiSettings::get_global(cx).disable_ai;
+ if assistant_enabled != AgentSettings::get_global(cx).enabled
+ || was_ai_disabled != is_ai_disabled
+ {
assistant_enabled = AgentSettings::get_global(cx).enabled;
+ was_ai_disabled = is_ai_disabled;
cx.notify();
}
});
@@ -1806,7 +1812,7 @@ impl GitPanel {
/// Generates a commit message using an LLM.
pub fn generate_commit_message(&mut self, cx: &mut Context<Self>) {
- if !self.can_commit() {
+ if !self.can_commit() || DisableAiSettings::get_global(cx).disable_ai {
return;
}
@@ -4305,8 +4311,10 @@ impl GitPanel {
}
fn current_language_model(cx: &Context<'_, GitPanel>) -> Option<Arc<dyn LanguageModel>> {
- agent_settings::AgentSettings::get_global(cx)
- .enabled
+ let is_enabled = agent_settings::AgentSettings::get_global(cx).enabled
+ && !DisableAiSettings::get_global(cx).disable_ai;
+
+ is_enabled
.then(|| {
let ConfiguredModel { provider, model } =
LanguageModelRegistry::read_global(cx).commit_message_model()?;
@@ -5037,6 +5045,7 @@ mod tests {
language::init(cx);
editor::init(cx);
Project::init_settings(cx);
+ client::DisableAiSettings::register(cx);
crate::init(cx);
});
}
@@ -1,5 +1,5 @@
use anyhow::Result;
-use client::{UserStore, zed_urls};
+use client::{DisableAiSettings, UserStore, zed_urls};
use copilot::{Copilot, Status};
use editor::{
Editor, SelectionEffects,
@@ -72,6 +72,11 @@ enum SupermavenButtonStatus {
impl Render for InlineCompletionButton {
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
+ // Return empty div if AI is disabled
+ if DisableAiSettings::get_global(cx).disable_ai {
+ return div();
+ }
+
let all_language_settings = all_language_settings(None, cx);
match all_language_settings.edit_predictions.provider {
@@ -1,4 +1,4 @@
-use client::{TelemetrySettings, telemetry::Telemetry};
+use client::{DisableAiSettings, TelemetrySettings, telemetry::Telemetry};
use db::kvp::KEY_VALUE_STORE;
use gpui::{
Action, App, Context, Entity, EventEmitter, FocusHandle, Focusable, InteractiveElement,
@@ -174,23 +174,25 @@ impl Render for WelcomePage {
.ok();
})),
)
- .child(
- Button::new(
- "try-zed-edit-prediction",
- edit_prediction_label,
+ .when(!DisableAiSettings::get_global(cx).disable_ai, |parent| {
+ parent.child(
+ Button::new(
+ "edit_prediction_onboarding",
+ edit_prediction_label,
+ )
+ .disabled(edit_prediction_provider_is_zed)
+ .icon(IconName::ZedPredict)
+ .icon_size(IconSize::XSmall)
+ .icon_color(Color::Muted)
+ .icon_position(IconPosition::Start)
+ .on_click(
+ cx.listener(|_, _, window, cx| {
+ telemetry::event!("Welcome Screen Try Edit Prediction clicked");
+ window.dispatch_action(zed_actions::OpenZedPredictOnboarding.boxed_clone(), cx);
+ }),
+ ),
)
- .disabled(edit_prediction_provider_is_zed)
- .icon(IconName::ZedPredict)
- .icon_size(IconSize::XSmall)
- .icon_color(Color::Muted)
- .icon_position(IconPosition::Start)
- .on_click(
- cx.listener(|_, _, window, cx| {
- telemetry::event!("Welcome Screen Try Edit Prediction clicked");
- window.dispatch_action(zed_actions::OpenZedPredictOnboarding.boxed_clone(), cx);
- }),
- ),
- )
+ })
.child(
Button::new("edit settings", "Edit Settings")
.icon(IconName::Settings)
@@ -242,6 +242,7 @@ struct PanelEntry {
pub struct PanelButtons {
dock: Entity<Dock>,
+ _settings_subscription: Subscription,
}
impl Dock {
@@ -373,6 +374,12 @@ impl Dock {
})
}
+ pub fn first_enabled_panel_idx_excluding(&self, exclude_name: &str, cx: &App) -> Option<usize> {
+ self.panel_entries.iter().position(|entry| {
+ entry.panel.persistent_name() != exclude_name && entry.panel.enabled(cx)
+ })
+ }
+
fn active_panel_entry(&self) -> Option<&PanelEntry> {
self.active_panel_index
.and_then(|index| self.panel_entries.get(index))
@@ -833,7 +840,11 @@ impl Render for Dock {
impl PanelButtons {
pub fn new(dock: Entity<Dock>, cx: &mut Context<Self>) -> Self {
cx.observe(&dock, |_, _, cx| cx.notify()).detach();
- Self { dock }
+ let settings_subscription = cx.observe_global::<SettingsStore>(|_, cx| cx.notify());
+ Self {
+ dock,
+ _settings_subscription: settings_subscription,
+ }
}
}
@@ -554,6 +554,7 @@ pub fn main() {
supermaven::init(app_state.client.clone(), cx);
language_model::init(app_state.client.clone(), cx);
language_models::init(app_state.user_store.clone(), app_state.client.clone(), cx);
+ agent_settings::init(cx);
agent_servers::init(cx);
web_search::init(cx);
web_search_providers::init(app_state.client.clone(), cx);
@@ -2,6 +2,7 @@ mod preview;
mod repl_menu;
use agent_settings::AgentSettings;
+use client::DisableAiSettings;
use editor::actions::{
AddSelectionAbove, AddSelectionBelow, CodeActionSource, DuplicateLineDown, GoToDiagnostic,
GoToHunk, GoToPreviousDiagnostic, GoToPreviousHunk, MoveLineDown, MoveLineUp, SelectAll,
@@ -32,6 +33,7 @@ const MAX_CODE_ACTION_MENU_LINES: u32 = 16;
pub struct QuickActionBar {
_inlay_hints_enabled_subscription: Option<Subscription>,
+ _ai_settings_subscription: Subscription,
active_item: Option<Box<dyn ItemHandle>>,
buffer_search_bar: Entity<BufferSearchBar>,
show: bool,
@@ -46,8 +48,28 @@ impl QuickActionBar {
workspace: &Workspace,
cx: &mut Context<Self>,
) -> Self {
+ let mut was_ai_disabled = DisableAiSettings::get_global(cx).disable_ai;
+ let mut was_agent_enabled = AgentSettings::get_global(cx).enabled;
+ let mut was_agent_button = AgentSettings::get_global(cx).button;
+
+ let ai_settings_subscription = cx.observe_global::<SettingsStore>(move |_, cx| {
+ let is_ai_disabled = DisableAiSettings::get_global(cx).disable_ai;
+ let agent_settings = AgentSettings::get_global(cx);
+
+ if was_ai_disabled != is_ai_disabled
+ || was_agent_enabled != agent_settings.enabled
+ || was_agent_button != agent_settings.button
+ {
+ was_ai_disabled = is_ai_disabled;
+ was_agent_enabled = agent_settings.enabled;
+ was_agent_button = agent_settings.button;
+ cx.notify();
+ }
+ });
+
let mut this = Self {
_inlay_hints_enabled_subscription: None,
+ _ai_settings_subscription: ai_settings_subscription,
active_item: None,
buffer_search_bar,
show: true,
@@ -575,7 +597,9 @@ impl Render for QuickActionBar {
.children(self.render_preview_button(self.workspace.clone(), cx))
.children(search_button)
.when(
- AgentSettings::get_global(cx).enabled && AgentSettings::get_global(cx).button,
+ AgentSettings::get_global(cx).enabled
+ && AgentSettings::get_global(cx).button
+ && !DisableAiSettings::get_global(cx).disable_ai,
|bar| bar.child(assistant_button),
)
.children(code_actions_dropdown)
@@ -1,10 +1,11 @@
use std::any::{Any, TypeId};
+use client::DisableAiSettings;
use command_palette_hooks::CommandPaletteFilter;
use feature_flags::{FeatureFlagAppExt as _, PredictEditsRateCompletionsFeatureFlag};
use gpui::actions;
use language::language_settings::{AllLanguageSettings, EditPredictionProvider};
-use settings::update_settings_file;
+use settings::{Settings, SettingsStore, update_settings_file};
use ui::App;
use workspace::Workspace;
@@ -21,6 +22,8 @@ actions!(
);
pub fn init(cx: &mut App) {
+ feature_gate_predict_edits_actions(cx);
+
cx.observe_new(move |workspace: &mut Workspace, _, _cx| {
workspace.register_action(|workspace, _: &RateCompletions, window, cx| {
if cx.has_flag::<PredictEditsRateCompletionsFeatureFlag>() {
@@ -53,27 +56,57 @@ pub fn init(cx: &mut App) {
});
})
.detach();
-
- feature_gate_predict_edits_rating_actions(cx);
}
-fn feature_gate_predict_edits_rating_actions(cx: &mut App) {
+fn feature_gate_predict_edits_actions(cx: &mut App) {
let rate_completion_action_types = [TypeId::of::<RateCompletions>()];
+ let reset_onboarding_action_types = [TypeId::of::<ResetOnboarding>()];
+ let zeta_all_action_types = [
+ TypeId::of::<RateCompletions>(),
+ TypeId::of::<ResetOnboarding>(),
+ zed_actions::OpenZedPredictOnboarding.type_id(),
+ TypeId::of::<crate::ClearHistory>(),
+ TypeId::of::<crate::ThumbsUpActiveCompletion>(),
+ TypeId::of::<crate::ThumbsDownActiveCompletion>(),
+ TypeId::of::<crate::NextEdit>(),
+ TypeId::of::<crate::PreviousEdit>(),
+ ];
CommandPaletteFilter::update_global(cx, |filter, _cx| {
filter.hide_action_types(&rate_completion_action_types);
+ filter.hide_action_types(&reset_onboarding_action_types);
filter.hide_action_types(&[zed_actions::OpenZedPredictOnboarding.type_id()]);
});
+ cx.observe_global::<SettingsStore>(move |cx| {
+ let is_ai_disabled = DisableAiSettings::get_global(cx).disable_ai;
+ let has_feature_flag = cx.has_flag::<PredictEditsRateCompletionsFeatureFlag>();
+
+ CommandPaletteFilter::update_global(cx, |filter, _cx| {
+ if is_ai_disabled {
+ filter.hide_action_types(&zeta_all_action_types);
+ } else {
+ if has_feature_flag {
+ filter.show_action_types(rate_completion_action_types.iter());
+ } else {
+ filter.hide_action_types(&rate_completion_action_types);
+ }
+ }
+ });
+ })
+ .detach();
+
cx.observe_flag::<PredictEditsRateCompletionsFeatureFlag, _>(move |is_enabled, cx| {
- if is_enabled {
- CommandPaletteFilter::update_global(cx, |filter, _cx| {
- filter.show_action_types(rate_completion_action_types.iter());
- });
- } else {
- CommandPaletteFilter::update_global(cx, |filter, _cx| {
- filter.hide_action_types(&rate_completion_action_types);
- });
+ if !DisableAiSettings::get_global(cx).disable_ai {
+ if is_enabled {
+ CommandPaletteFilter::update_global(cx, |filter, _cx| {
+ filter.show_action_types(rate_completion_action_types.iter());
+ });
+ } else {
+ CommandPaletteFilter::update_global(cx, |filter, _cx| {
+ filter.hide_action_types(&rate_completion_action_types);
+ });
+ }
}
})
.detach();