diff --git a/assets/settings/default.json b/assets/settings/default.json index e0cbf75aec542f7d9005cfd7618cdc9dbc83f230..f62cc1844732db2a49dc835a155e861f4268632f 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -1329,7 +1329,7 @@ "model": null, "max_tokens": null }, - // Whether edit predictions are enabled when editing text threads. + // Whether edit predictions are enabled when editing text threads in the agent panel. // This setting has no effect if globally disabled. "enabled_in_text_threads": true }, diff --git a/crates/settings/src/settings_content/language.rs b/crates/settings/src/settings_content/language.rs index 5c74662f0204fd8ef15099c8e8e2e5629963d703..a0a8aff3ae82a9001eb52367ab315912b5aac609 100644 --- a/crates/settings/src/settings_content/language.rs +++ b/crates/settings/src/settings_content/language.rs @@ -151,7 +151,18 @@ pub struct CodestralSettingsContent { /// The mode in which edit predictions should be displayed. #[derive( - Copy, Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom, + Copy, + Clone, + Debug, + Default, + Eq, + PartialEq, + Serialize, + Deserialize, + JsonSchema, + MergeFrom, + strum::VariantArray, + strum::VariantNames, )] #[serde(rename_all = "snake_case")] pub enum EditPredictionsMode { diff --git a/crates/settings_ui/src/page_data.rs b/crates/settings_ui/src/page_data.rs index db791c0ab35882163226e58888ee2bb54d30c5a2..915d34e1087823841e985bb141879bf781db64fb 100644 --- a/crates/settings_ui/src/page_data.rs +++ b/crates/settings_ui/src/page_data.rs @@ -2323,6 +2323,7 @@ pub(crate) fn settings_data(cx: &App) -> Vec { language_settings_data() .iter() .chain(non_editor_language_settings_data().iter()) + .chain(edit_prediction_language_settings_section().iter()) .enumerate(), None, window, @@ -5512,209 +5513,283 @@ pub(crate) fn settings_data(cx: &App) -> Vec { }, SettingsPage { title: "AI", - items: vec![ - SettingsPageItem::SectionHeader("General"), - SettingsPageItem::SettingItem(SettingItem { - title: "Disable AI", - description: "Whether to disable all AI features in Zed.", - field: Box::new(SettingField { - json_path: Some("disable_ai"), - pick: |settings_content| settings_content.disable_ai.as_ref(), - write: |settings_content, value| { - settings_content.disable_ai = value; - }, + items: { + let mut items = vec![ + SettingsPageItem::SectionHeader("General"), + SettingsPageItem::SettingItem(SettingItem { + title: "Disable AI", + description: "Whether to disable all AI features in Zed.", + field: Box::new(SettingField { + json_path: Some("disable_ai"), + pick: |settings_content| settings_content.disable_ai.as_ref(), + write: |settings_content, value| { + settings_content.disable_ai = value; + }, + }), + metadata: None, + files: USER, }), - metadata: None, - files: USER, - }), - SettingsPageItem::SectionHeader("Agent Configuration"), - SettingsPageItem::SettingItem(SettingItem { - title: "Always Allow Tool Actions", - description: "When enabled, the agent can run potentially destructive actions without asking for your confirmation. This setting has no effect on external agents.", - field: Box::new(SettingField { - json_path: Some("agent.always_allow_tool_actions"), - pick: |settings_content| { - settings_content - .agent - .as_ref()? - .always_allow_tool_actions - .as_ref() - }, - write: |settings_content, value| { - settings_content - .agent - .get_or_insert_default() - .always_allow_tool_actions = value; - }, + SettingsPageItem::SectionHeader("Agent Configuration"), + SettingsPageItem::SettingItem(SettingItem { + title: "Always Allow Tool Actions", + description: "When enabled, the agent can run potentially destructive actions without asking for your confirmation. This setting has no effect on external agents.", + field: Box::new(SettingField { + json_path: Some("agent.always_allow_tool_actions"), + pick: |settings_content| { + settings_content + .agent + .as_ref()? + .always_allow_tool_actions + .as_ref() + }, + write: |settings_content, value| { + settings_content + .agent + .get_or_insert_default() + .always_allow_tool_actions = value; + }, + }), + metadata: None, + files: USER, }), - metadata: None, - files: USER, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Single File Review", - description: "When enabled, agent edits will also be displayed in single-file buffers for review.", - field: Box::new(SettingField { - json_path: Some("agent.single_file_review"), - pick: |settings_content| { - settings_content.agent.as_ref()?.single_file_review.as_ref() - }, - write: |settings_content, value| { - settings_content - .agent - .get_or_insert_default() - .single_file_review = value; - }, + SettingsPageItem::SettingItem(SettingItem { + title: "Single File Review", + description: "When enabled, agent edits will also be displayed in single-file buffers for review.", + field: Box::new(SettingField { + json_path: Some("agent.single_file_review"), + pick: |settings_content| { + settings_content.agent.as_ref()?.single_file_review.as_ref() + }, + write: |settings_content, value| { + settings_content + .agent + .get_or_insert_default() + .single_file_review = value; + }, + }), + metadata: None, + files: USER, }), - metadata: None, - files: USER, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Enable Feedback", - description: "Show voting thumbs up/down icon buttons for feedback on agent edits.", - field: Box::new(SettingField { - json_path: Some("agent.enable_feedback"), - pick: |settings_content| { - settings_content.agent.as_ref()?.enable_feedback.as_ref() - }, - write: |settings_content, value| { - settings_content - .agent - .get_or_insert_default() - .enable_feedback = value; - }, + SettingsPageItem::SettingItem(SettingItem { + title: "Enable Feedback", + description: "Show voting thumbs up/down icon buttons for feedback on agent edits.", + field: Box::new(SettingField { + json_path: Some("agent.enable_feedback"), + pick: |settings_content| { + settings_content.agent.as_ref()?.enable_feedback.as_ref() + }, + write: |settings_content, value| { + settings_content + .agent + .get_or_insert_default() + .enable_feedback = value; + }, + }), + metadata: None, + files: USER, }), - metadata: None, - files: USER, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Notify When Agent Waiting", - description: "Where to show notifications when the agent has completed its response or needs confirmation before running a tool action.", - field: Box::new(SettingField { - json_path: Some("agent.notify_when_agent_waiting"), - pick: |settings_content| { - settings_content - .agent - .as_ref()? - .notify_when_agent_waiting - .as_ref() - }, - write: |settings_content, value| { - settings_content - .agent - .get_or_insert_default() - .notify_when_agent_waiting = value; - }, + SettingsPageItem::SettingItem(SettingItem { + title: "Notify When Agent Waiting", + description: "Where to show notifications when the agent has completed its response or needs confirmation before running a tool action.", + field: Box::new(SettingField { + json_path: Some("agent.notify_when_agent_waiting"), + pick: |settings_content| { + settings_content + .agent + .as_ref()? + .notify_when_agent_waiting + .as_ref() + }, + write: |settings_content, value| { + settings_content + .agent + .get_or_insert_default() + .notify_when_agent_waiting = value; + }, + }), + metadata: None, + files: USER, }), - metadata: None, - files: USER, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Play Sound When Agent Done", - description: "Whether to play a sound when the agent has either completed its response, or needs user input.", - field: Box::new(SettingField { - json_path: Some("agent.play_sound_when_agent_done"), - pick: |settings_content| { - settings_content - .agent - .as_ref()? - .play_sound_when_agent_done - .as_ref() - }, - write: |settings_content, value| { - settings_content - .agent - .get_or_insert_default() - .play_sound_when_agent_done = value; - }, + SettingsPageItem::SettingItem(SettingItem { + title: "Play Sound When Agent Done", + description: "Whether to play a sound when the agent has either completed its response, or needs user input.", + field: Box::new(SettingField { + json_path: Some("agent.play_sound_when_agent_done"), + pick: |settings_content| { + settings_content + .agent + .as_ref()? + .play_sound_when_agent_done + .as_ref() + }, + write: |settings_content, value| { + settings_content + .agent + .get_or_insert_default() + .play_sound_when_agent_done = value; + }, + }), + metadata: None, + files: USER, }), - metadata: None, - files: USER, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Expand Edit Card", - description: "Whether to have edit cards in the agent panel expanded, showing a Preview of the diff.", - field: Box::new(SettingField { - json_path: Some("agent.expand_edit_card"), - pick: |settings_content| { - settings_content.agent.as_ref()?.expand_edit_card.as_ref() - }, - write: |settings_content, value| { - settings_content - .agent - .get_or_insert_default() - .expand_edit_card = value; - }, + SettingsPageItem::SettingItem(SettingItem { + title: "Expand Edit Card", + description: "Whether to have edit cards in the agent panel expanded, showing a Preview of the diff.", + field: Box::new(SettingField { + json_path: Some("agent.expand_edit_card"), + pick: |settings_content| { + settings_content.agent.as_ref()?.expand_edit_card.as_ref() + }, + write: |settings_content, value| { + settings_content + .agent + .get_or_insert_default() + .expand_edit_card = value; + }, + }), + metadata: None, + files: USER, }), - metadata: None, - files: USER, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Expand Terminal Card", - description: "Whether to have terminal cards in the agent panel expanded, showing the whole command output.", - field: Box::new(SettingField { - json_path: Some("agent.expand_terminal_card"), - pick: |settings_content| { - settings_content - .agent - .as_ref()? - .expand_terminal_card - .as_ref() - }, - write: |settings_content, value| { - settings_content - .agent - .get_or_insert_default() - .expand_terminal_card = value; - }, + SettingsPageItem::SettingItem(SettingItem { + title: "Expand Terminal Card", + description: "Whether to have terminal cards in the agent panel expanded, showing the whole command output.", + field: Box::new(SettingField { + json_path: Some("agent.expand_terminal_card"), + pick: |settings_content| { + settings_content + .agent + .as_ref()? + .expand_terminal_card + .as_ref() + }, + write: |settings_content, value| { + settings_content + .agent + .get_or_insert_default() + .expand_terminal_card = value; + }, + }), + metadata: None, + files: USER, }), - metadata: None, - files: USER, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Use Modifier To Send", - description: "Whether to always use cmd-enter (or ctrl-enter on Linux or Windows) to send messages.", - field: Box::new(SettingField { - json_path: Some("agent.use_modifier_to_send"), - pick: |settings_content| { - settings_content - .agent - .as_ref()? - .use_modifier_to_send - .as_ref() - }, - write: |settings_content, value| { - settings_content - .agent - .get_or_insert_default() - .use_modifier_to_send = value; - }, + SettingsPageItem::SettingItem(SettingItem { + title: "Use Modifier To Send", + description: "Whether to always use cmd-enter (or ctrl-enter on Linux or Windows) to send messages.", + field: Box::new(SettingField { + json_path: Some("agent.use_modifier_to_send"), + pick: |settings_content| { + settings_content + .agent + .as_ref()? + .use_modifier_to_send + .as_ref() + }, + write: |settings_content, value| { + settings_content + .agent + .get_or_insert_default() + .use_modifier_to_send = value; + }, + }), + metadata: None, + files: USER, }), - metadata: None, - files: USER, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Message Editor Min Lines", - description: "Minimum number of lines to display in the agent message editor.", - field: Box::new(SettingField { - json_path: Some("agent.message_editor_min_lines"), - pick: |settings_content| { - settings_content - .agent - .as_ref()? - .message_editor_min_lines - .as_ref() - }, - write: |settings_content, value| { - settings_content - .agent - .get_or_insert_default() - .message_editor_min_lines = value; - }, + SettingsPageItem::SettingItem(SettingItem { + title: "Message Editor Min Lines", + description: "Minimum number of lines to display in the agent message editor.", + field: Box::new(SettingField { + json_path: Some("agent.message_editor_min_lines"), + pick: |settings_content| { + settings_content + .agent + .as_ref()? + .message_editor_min_lines + .as_ref() + }, + write: |settings_content, value| { + settings_content + .agent + .get_or_insert_default() + .message_editor_min_lines = value; + }, + }), + metadata: None, + files: USER, }), - metadata: None, - files: USER, - }), - ], + ]; + items.extend(edit_prediction_language_settings_section()); + items.extend( + [ + SettingsPageItem::SettingItem(SettingItem { + title: "Display Mode", + description: "When to show edit predictions previews in buffer. The eager mode displays them inline, while the subtle mode displays them only when holding a modifier key.", + field: Box::new(SettingField { + json_path: Some("edit_prediction_mode"), + pick: |settings_content| { + settings_content.project.all_languages.edit_predictions.as_ref()?.mode.as_ref() + }, + write: |settings_content, value| { + settings_content.project.all_languages.edit_predictions.get_or_insert_default().mode = value; + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "In Text Threads", + description: "Whether edit predictions are enabled when editing text threads in the agent panel.", + field: Box::new(SettingField { + json_path: Some("edit_prediction_in_text_threads"), + pick: |settings_content| { + settings_content.project.all_languages.edit_predictions.as_ref()?.enabled_in_text_threads.as_ref() + }, + write: |settings_content, value| { + settings_content.project.all_languages.edit_predictions.get_or_insert_default().enabled_in_text_threads = value; + }, + }), + metadata: None, + files: USER, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Copilot Provider", + description: "Set up GitHub Copilot as your edit prediction provider. You can toggle between it and Zed's default provider.", + field: Box::new( + SettingField { + json_path: Some("languages.$(language).wrap_guides"), + pick: |settings_content| { + settings_content.project.all_languages.edit_predictions.as_ref()?.copilot.as_ref() + }, + write: |settings_content, value| { + settings_content.project.all_languages.edit_predictions.get_or_insert_default().copilot = value; + }, + } + .unimplemented(), + ), + metadata: None, + files: USER | PROJECT, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Codestral Provider", + description: "Set up Mistral's Codestral as your edit prediction provider. You can toggle between it and Zed's default provider.", + field: Box::new( + SettingField { + json_path: Some("languages.$(language).wrap_guides"), + pick: |settings_content| { + settings_content.project.all_languages.edit_predictions.as_ref()?.codestral.as_ref() + }, + write: |settings_content, value| { + settings_content.project.all_languages.edit_predictions.get_or_insert_default().codestral = value; + }, + } + .unimplemented(), + ), + metadata: None, + files: USER | PROJECT, + }), + ] + ); + items + }, }, SettingsPage { title: "Network", @@ -6299,48 +6374,6 @@ fn language_settings_data() -> Vec { metadata: None, files: USER | PROJECT, }), - SettingsPageItem::SectionHeader("Edit Predictions"), - SettingsPageItem::SettingItem(SettingItem { - title: "Show Edit Predictions", - description: "Controls whether edit predictions are shown immediately (true) or manually by triggering `editor::showeditprediction` (false).", - field: Box::new(SettingField { - json_path: Some("languages.$(language).show_edit_predictions"), - pick: |settings_content| { - language_settings_field(settings_content, |language| { - language.show_edit_predictions.as_ref() - }) - }, - write: |settings_content, value| { - language_settings_field_mut(settings_content, value, |language, value| { - language.show_edit_predictions = value; - }) - }, - }), - metadata: None, - files: USER | PROJECT, - }), - SettingsPageItem::SettingItem(SettingItem { - title: "Edit Predictions Disabled In", - description: "Controls whether edit predictions are shown in the given language scopes.", - field: Box::new( - SettingField { - json_path: Some("languages.$(language).edit_predictions_disabled_in"), - pick: |settings_content| { - language_settings_field(settings_content, |language| { - language.edit_predictions_disabled_in.as_ref() - }) - }, - write: |settings_content, value| { - language_settings_field_mut(settings_content, value, |language, value| { - language.edit_predictions_disabled_in = value; - }) - }, - } - .unimplemented(), - ), - metadata: None, - files: USER | PROJECT, - }), SettingsPageItem::SectionHeader("Whitespace"), SettingsPageItem::SettingItem(SettingItem { title: "Show Whitespaces", @@ -7121,6 +7154,53 @@ fn non_editor_language_settings_data() -> Vec { ] } +fn edit_prediction_language_settings_section() -> Vec { + vec![ + SettingsPageItem::SectionHeader("Edit Predictions"), + SettingsPageItem::SettingItem(SettingItem { + title: "Show Edit Predictions", + description: "Controls whether edit predictions are shown immediately or manually by triggering `editor::showeditprediction` (false).", + field: Box::new(SettingField { + json_path: Some("languages.$(language).show_edit_predictions"), + pick: |settings_content| { + language_settings_field(settings_content, |language| { + language.show_edit_predictions.as_ref() + }) + }, + write: |settings_content, value| { + language_settings_field_mut(settings_content, value, |language, value| { + language.show_edit_predictions = value; + }) + }, + }), + metadata: None, + files: USER | PROJECT, + }), + SettingsPageItem::SettingItem(SettingItem { + title: "Edit Predictions Disabled In", + description: "Controls whether edit predictions are shown in the given language scopes.", + field: Box::new( + SettingField { + json_path: Some("languages.$(language).edit_predictions_disabled_in"), + pick: |settings_content| { + language_settings_field(settings_content, |language| { + language.edit_predictions_disabled_in.as_ref() + }) + }, + write: |settings_content, value| { + language_settings_field_mut(settings_content, value, |language, value| { + language.edit_predictions_disabled_in = value; + }) + }, + } + .unimplemented(), + ), + metadata: None, + files: USER | PROJECT, + }), + ] +} + fn show_scrollbar_or_editor( settings_content: &SettingsContent, show: fn(&SettingsContent) -> Option<&settings::ShowScrollbar>, diff --git a/crates/settings_ui/src/settings_ui.rs b/crates/settings_ui/src/settings_ui.rs index b2cc1dcf1321fde9c54e3fc4b7abdedb3dd40d93..14e2eaf688f39f6d50fbdcb1102df28e3fa0975e 100644 --- a/crates/settings_ui/src/settings_ui.rs +++ b/crates/settings_ui/src/settings_ui.rs @@ -496,6 +496,7 @@ fn init_renderers(cx: &mut App) { .add_basic_renderer::(render_dropdown) .add_basic_renderer::(render_dropdown) .add_basic_renderer::(render_dropdown) + .add_basic_renderer::(render_dropdown) // please semicolon stay on next line ; }