diff --git a/assets/settings/default.json b/assets/settings/default.json index 0f663e1b8148eda2c8762957ca5738ba6f0dfea2..1ecfbf03a1c4ec801a008371427b8f55f77b09e5 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -1,6 +1,11 @@ { // The name of the Zed theme to use for the UI "theme": "One Dark", + // Features that can be globally enabled or disabled + "features": { + // Show Copilot icon in status bar + "copilot": true + }, // The name of a font to use for rendering text in the editor "buffer_font_family": "Zed Mono", // The OpenType features to enable for text in the editor. @@ -13,11 +18,6 @@ // The factor to grow the active pane by. Defaults to 1.0 // which gives the same size as all other panes. "active_pane_magnification": 1.0, - // Enable / disable copilot integration. - "enable_copilot_integration": true, - // Controls whether copilot provides suggestion immediately - // or waits for a `copilot::Toggle` - "copilot": "on", // Whether to enable vim modes and key bindings "vim_mode": false, // Whether to show the informational hover box when moving the mouse @@ -30,6 +30,9 @@ // Whether to pop the completions menu while typing in an editor without // explicitly requesting it. "show_completions_on_input": true, + // Controls whether copilot provides suggestion immediately + // or waits for a `copilot::Toggle` + "show_copilot_suggestions": true, // Whether the screen sharing icon is shown in the os status bar. "show_call_status_icon": true, // Whether to use language servers to provide code intelligence. diff --git a/crates/copilot/src/copilot.rs b/crates/copilot/src/copilot.rs index 43fcf55e958e7ca2c05cd350df3dc4fcb5fa2c77..aa086775b3b0ef1652de8b72554fcc591faa55fb 100644 --- a/crates/copilot/src/copilot.rs +++ b/crates/copilot/src/copilot.rs @@ -172,7 +172,7 @@ impl Copilot { let http = http.clone(); let node_runtime = node_runtime.clone(); move |this, cx| { - if cx.global::().enable_copilot_integration { + if cx.global::().features.copilot { if matches!(this.server, CopilotServer::Disabled) { let start_task = cx .spawn({ @@ -194,7 +194,7 @@ impl Copilot { }) .detach(); - if cx.global::().enable_copilot_integration { + if cx.global::().features.copilot { let start_task = cx .spawn({ let http = http.clone(); diff --git a/crates/copilot_button/src/copilot_button.rs b/crates/copilot_button/src/copilot_button.rs index 872182924166830416a1c779f89d477798ea147b..b3269986165d607b622b20f119ebc722ec24b03c 100644 --- a/crates/copilot_button/src/copilot_button.rs +++ b/crates/copilot_button/src/copilot_button.rs @@ -50,15 +50,16 @@ pub fn init(cx: &mut AppContext) { cx.add_action(CopilotButton::deploy_copilot_menu); cx.add_action( |_: &mut CopilotButton, action: &ToggleCopilotForLanguage, cx| { - let language = action.language.to_owned(); - - let current_langauge = cx.global::().copilot_on(Some(&language)); + let language = action.language.clone(); + let show_copilot_suggestions = cx + .global::() + .show_copilot_suggestions(Some(&language)); SettingsFile::update(cx, move |file_contents| { file_contents.languages.insert( - language.to_owned(), + language, settings::EditorSettings { - copilot: Some((!current_langauge).into()), + show_copilot_suggestions: Some((!show_copilot_suggestions).into()), ..Default::default() }, ); @@ -67,10 +68,9 @@ pub fn init(cx: &mut AppContext) { ); cx.add_action(|_: &mut CopilotButton, _: &ToggleCopilotGlobally, cx| { - let copilot_on = cx.global::().copilot_on(None); - + let show_copilot_suggestions = cx.global::().show_copilot_suggestions(None); SettingsFile::update(cx, move |file_contents| { - file_contents.editor.copilot = Some((!copilot_on).into()) + file_contents.editor.show_copilot_suggestions = Some((!show_copilot_suggestions).into()) }) }); } @@ -94,7 +94,7 @@ impl View for CopilotButton { fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox { let settings = cx.global::(); - if !settings.enable_copilot_integration { + if !settings.features.copilot { return Empty::new().boxed(); } @@ -105,7 +105,9 @@ impl View for CopilotButton { }; let status = copilot.read(cx).status(); - let enabled = self.editor_enabled.unwrap_or(settings.copilot_on(None)); + let enabled = self + .editor_enabled + .unwrap_or(settings.show_copilot_suggestions(None)); let view_id = cx.view_id(); @@ -248,7 +250,7 @@ impl CopilotButton { let mut menu_options = Vec::with_capacity(6); if let Some(language) = &self.language { - let language_enabled = settings.copilot_on(Some(language.as_ref())); + let language_enabled = settings.show_copilot_suggestions(Some(language.as_ref())); menu_options.push(ContextMenuItem::item( format!( @@ -266,7 +268,7 @@ impl CopilotButton { )); } - let globally_enabled = cx.global::().copilot_on(None); + let globally_enabled = cx.global::().show_copilot_suggestions(None); menu_options.push(ContextMenuItem::item( if globally_enabled { "Disable Copilot Globally" @@ -319,7 +321,7 @@ impl CopilotButton { self.language = language_name.clone(); - self.editor_enabled = Some(settings.copilot_on(language_name.as_deref())); + self.editor_enabled = Some(settings.show_copilot_suggestions(language_name.as_deref())); cx.notify() } diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index b3f3723bc1adb7d1fa828207e9a46b4517cc3b35..2d39416858d903c7535ff99e694aee292ad3858c 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -2816,7 +2816,10 @@ impl Editor { let snapshot = self.buffer.read(cx).snapshot(cx); let cursor = self.selections.newest_anchor().head(); let language_name = snapshot.language_at(cursor).map(|language| language.name()); - if !cx.global::().copilot_on(language_name.as_deref()) { + if !cx + .global::() + .show_copilot_suggestions(language_name.as_deref()) + { self.hide_copilot_suggestion(cx); return None; } diff --git a/crates/settings/src/settings.rs b/crates/settings/src/settings.rs index feb4017018098ffd7040e3ec2c1416b055658c8f..6942a6e57b70465fd8942df69668705087737244 100644 --- a/crates/settings/src/settings.rs +++ b/crates/settings/src/settings.rs @@ -28,11 +28,11 @@ pub use watched_json::watch_files; #[derive(Clone)] pub struct Settings { + pub features: Features, pub buffer_font_family_name: String, pub buffer_font_features: fonts::Features, pub buffer_font_family: FamilyId, pub default_buffer_font_size: f32, - pub enable_copilot_integration: bool, pub buffer_font_size: f32, pub active_pane_magnification: f32, pub cursor_blink: bool, @@ -177,43 +177,7 @@ pub struct EditorSettings { pub ensure_final_newline_on_save: Option, pub formatter: Option, pub enable_language_server: Option, - #[schemars(skip)] - pub copilot: Option, -} - -#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum OnOff { - On, - Off, -} - -impl OnOff { - pub fn as_bool(&self) -> bool { - match self { - OnOff::On => true, - OnOff::Off => false, - } - } - - pub fn from_bool(value: bool) -> OnOff { - match value { - true => OnOff::On, - false => OnOff::Off, - } - } -} - -impl From for bool { - fn from(value: OnOff) -> bool { - value.as_bool() - } -} - -impl From for OnOff { - fn from(value: bool) -> OnOff { - OnOff::from_bool(value) - } + pub show_copilot_suggestions: Option, } #[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] @@ -437,8 +401,7 @@ pub struct SettingsFileContent { #[serde(default)] pub base_keymap: Option, #[serde(default)] - #[schemars(skip)] - pub enable_copilot_integration: Option, + pub features: FeaturesContent, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] @@ -447,6 +410,18 @@ pub struct LspSettings { pub initialization_options: Option, } +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub struct Features { + pub copilot: bool, +} + +#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub struct FeaturesContent { + pub copilot: Option, +} + impl Settings { /// Fill out the settings corresponding to the default.json file, overrides will be set later pub fn defaults( @@ -500,7 +475,7 @@ impl Settings { format_on_save: required(defaults.editor.format_on_save), formatter: required(defaults.editor.formatter), enable_language_server: required(defaults.editor.enable_language_server), - copilot: required(defaults.editor.copilot), + show_copilot_suggestions: required(defaults.editor.show_copilot_suggestions), }, editor_overrides: Default::default(), git: defaults.git.unwrap(), @@ -517,7 +492,9 @@ impl Settings { telemetry_overrides: Default::default(), auto_update: defaults.auto_update.unwrap(), base_keymap: Default::default(), - enable_copilot_integration: defaults.enable_copilot_integration.unwrap(), + features: Features { + copilot: defaults.features.copilot.unwrap(), + }, } } @@ -569,10 +546,7 @@ impl Settings { merge(&mut self.autosave, data.autosave); merge(&mut self.default_dock_anchor, data.default_dock_anchor); merge(&mut self.base_keymap, data.base_keymap); - merge( - &mut self.enable_copilot_integration, - data.enable_copilot_integration, - ); + merge(&mut self.features.copilot, data.features.copilot); self.editor_overrides = data.editor; self.git_overrides = data.git.unwrap_or_default(); @@ -596,12 +570,15 @@ impl Settings { self } - pub fn copilot_on(&self, language: Option<&str>) -> bool { - if self.enable_copilot_integration { - self.language_setting(language, |settings| settings.copilot.map(Into::into)) - } else { - false - } + pub fn features(&self) -> &Features { + &self.features + } + + pub fn show_copilot_suggestions(&self, language: Option<&str>) -> bool { + self.features.copilot + && self.language_setting(language, |settings| { + settings.show_copilot_suggestions.map(Into::into) + }) } pub fn tab_size(&self, language: Option<&str>) -> NonZeroU32 { @@ -740,7 +717,7 @@ impl Settings { format_on_save: Some(FormatOnSave::On), formatter: Some(Formatter::LanguageServer), enable_language_server: Some(true), - copilot: Some(OnOff::On), + show_copilot_suggestions: Some(true), }, editor_overrides: Default::default(), journal_defaults: Default::default(), @@ -760,7 +737,7 @@ impl Settings { telemetry_overrides: Default::default(), auto_update: true, base_keymap: Default::default(), - enable_copilot_integration: true, + features: Features { copilot: true }, } } @@ -1125,7 +1102,7 @@ mod tests { { "language_overrides": { "JSON": { - "copilot": "off" + "show_copilot_suggestions": false } } } @@ -1135,7 +1112,7 @@ mod tests { settings.languages.insert( "Rust".into(), EditorSettings { - copilot: Some(OnOff::On), + show_copilot_suggestions: Some(true), ..Default::default() }, ); @@ -1144,10 +1121,10 @@ mod tests { { "language_overrides": { "Rust": { - "copilot": "on" + "show_copilot_suggestions": true }, "JSON": { - "copilot": "off" + "show_copilot_suggestions": false } } } @@ -1163,21 +1140,21 @@ mod tests { { "languages": { "JSON": { - "copilot": "off" + "show_copilot_suggestions": false } } } "# .unindent(), |settings| { - settings.editor.copilot = Some(OnOff::On); + settings.editor.show_copilot_suggestions = Some(true); }, r#" { - "copilot": "on", + "show_copilot_suggestions": true, "languages": { "JSON": { - "copilot": "off" + "show_copilot_suggestions": false } } } @@ -1187,13 +1164,13 @@ mod tests { } #[test] - fn test_update_langauge_copilot() { + fn test_update_language_copilot() { assert_new_settings( r#" { "languages": { "JSON": { - "copilot": "off" + "show_copilot_suggestions": false } } } @@ -1203,7 +1180,7 @@ mod tests { settings.languages.insert( "Rust".into(), EditorSettings { - copilot: Some(OnOff::On), + show_copilot_suggestions: Some(true), ..Default::default() }, ); @@ -1212,10 +1189,10 @@ mod tests { { "languages": { "Rust": { - "copilot": "on" + "show_copilot_suggestions": true }, "JSON": { - "copilot": "off" + "show_copilot_suggestions": false } } }