settings: Use a derive macro for refine (#38451)
When we refactored settings to not pass JSON blobs around, we ended up needing to write *a lot* of code that just merged things (like json merge used to do). Use a derive macro to prevent typos in this logic. Release Notes: - N/A
This commit is contained in:
@@ -2,21 +2,17 @@ use std::fmt::{Display, Formatter};
|
||||
|
||||
use crate::{
|
||||
self as settings,
|
||||
settings_content::{self, BaseKeymapContent, SettingsContent},
|
||||
settings_content::{BaseKeymapContent, SettingsContent},
|
||||
};
|
||||
use gpui::App;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::skip_serializing_none;
|
||||
use settings::{Settings, VsCodeSettings};
|
||||
use settings_ui_macros::{SettingsKey, SettingsUi};
|
||||
|
||||
/// Base key bindings scheme. Base keymaps can be overridden with user keymaps.
|
||||
///
|
||||
/// Default: VSCode
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Default, SettingsUi,
|
||||
)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Default)]
|
||||
pub enum BaseKeymap {
|
||||
#[default]
|
||||
VSCode,
|
||||
@@ -134,37 +130,11 @@ impl BaseKeymap {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Copy,
|
||||
Clone,
|
||||
Debug,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
JsonSchema,
|
||||
PartialEq,
|
||||
Eq,
|
||||
Default,
|
||||
SettingsUi,
|
||||
SettingsKey,
|
||||
)]
|
||||
// extracted so that it can be an option, and still work with derive(SettingsUi)
|
||||
#[settings_key(None)]
|
||||
#[skip_serializing_none]
|
||||
pub struct BaseKeymapSetting {
|
||||
pub base_keymap: Option<BaseKeymap>,
|
||||
}
|
||||
|
||||
impl Settings for BaseKeymap {
|
||||
fn from_defaults(s: &crate::settings_content::SettingsContent, _cx: &mut App) -> Self {
|
||||
fn from_settings(s: &crate::settings_content::SettingsContent, _cx: &mut App) -> Self {
|
||||
s.base_keymap.unwrap().into()
|
||||
}
|
||||
|
||||
fn refine(&mut self, s: &settings_content::SettingsContent, _cx: &mut App) {
|
||||
if let Some(base_keymap) = s.base_keymap {
|
||||
*self = base_keymap.into();
|
||||
};
|
||||
}
|
||||
|
||||
fn import_from_vscode(_vscode: &VsCodeSettings, current: &mut SettingsContent) {
|
||||
current.base_keymap = Some(BaseKeymapContent::VSCode);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
/// Trait for recursively merging settings structures.
|
||||
///
|
||||
/// This trait allows settings objects to be merged from optional sources,
|
||||
/// where `None` values are ignored and `Some` values override existing values.
|
||||
///
|
||||
/// HashMaps, structs and similar types are merged by combining their contents key-wise,
|
||||
/// but all other types (including Vecs) are last-write-wins.
|
||||
/// (Though see also ExtendingVec and SaturatingBool)
|
||||
#[allow(unused)]
|
||||
pub trait MergeFrom {
|
||||
/// Merge from an optional source of the same type.
|
||||
/// If `other` is `None`, no changes are made.
|
||||
/// If `other` is `Some(value)`, fields from `value` are merged into `self`.
|
||||
fn merge_from(&mut self, other: Option<&Self>);
|
||||
}
|
||||
|
||||
macro_rules! merge_from_overwrites {
|
||||
($($type:ty),+) => {
|
||||
$(
|
||||
impl MergeFrom for $type {
|
||||
fn merge_from(&mut self, other: Option<&Self>) {
|
||||
if let Some(value) = other {
|
||||
*self = value.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
merge_from_overwrites!(
|
||||
u16,
|
||||
u32,
|
||||
u64,
|
||||
usize,
|
||||
i16,
|
||||
i32,
|
||||
i64,
|
||||
bool,
|
||||
f64,
|
||||
f32,
|
||||
std::num::NonZeroUsize,
|
||||
std::num::NonZeroU32,
|
||||
String,
|
||||
std::sync::Arc<str>,
|
||||
gpui::SharedString,
|
||||
std::path::PathBuf,
|
||||
gpui::Modifiers,
|
||||
gpui::FontFeatures
|
||||
);
|
||||
|
||||
impl<T: Clone> MergeFrom for Vec<T> {
|
||||
fn merge_from(&mut self, other: Option<&Self>) {
|
||||
if let Some(other) = other {
|
||||
*self = other.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implementations for collections that extend/merge their contents
|
||||
impl<K, V> MergeFrom for collections::HashMap<K, V>
|
||||
where
|
||||
K: Clone + std::hash::Hash + Eq,
|
||||
V: Clone + MergeFrom,
|
||||
{
|
||||
fn merge_from(&mut self, other: Option<&Self>) {
|
||||
let Some(other) = other else { return };
|
||||
for (k, v) in other {
|
||||
if let Some(existing) = self.get_mut(k) {
|
||||
existing.merge_from(Some(v));
|
||||
} else {
|
||||
self.insert(k.clone(), v.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> MergeFrom for collections::BTreeMap<K, V>
|
||||
where
|
||||
K: Clone + std::hash::Hash + Eq + Ord,
|
||||
V: Clone + MergeFrom,
|
||||
{
|
||||
fn merge_from(&mut self, other: Option<&Self>) {
|
||||
let Some(other) = other else { return };
|
||||
for (k, v) in other {
|
||||
if let Some(existing) = self.get_mut(k) {
|
||||
existing.merge_from(Some(v));
|
||||
} else {
|
||||
self.insert(k.clone(), v.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> MergeFrom for collections::IndexMap<K, V>
|
||||
where
|
||||
K: std::hash::Hash + Eq + Clone,
|
||||
// Q: ?Sized + std::hash::Hash + collections::Equivalent<K> + Eq,
|
||||
V: Clone + MergeFrom,
|
||||
{
|
||||
fn merge_from(&mut self, other: Option<&Self>) {
|
||||
let Some(other) = other else { return };
|
||||
for (k, v) in other {
|
||||
if let Some(existing) = self.get_mut(k) {
|
||||
existing.merge_from(Some(v));
|
||||
} else {
|
||||
self.insert(k.clone(), v.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> MergeFrom for collections::BTreeSet<T>
|
||||
where
|
||||
T: Clone + Ord,
|
||||
{
|
||||
fn merge_from(&mut self, other: Option<&Self>) {
|
||||
let Some(other) = other else { return };
|
||||
for item in other {
|
||||
self.insert(item.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> MergeFrom for collections::HashSet<T>
|
||||
where
|
||||
T: Clone + std::hash::Hash + Eq,
|
||||
{
|
||||
fn merge_from(&mut self, other: Option<&Self>) {
|
||||
let Some(other) = other else { return };
|
||||
for item in other {
|
||||
self.insert(item.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MergeFrom for serde_json::Value {
|
||||
fn merge_from(&mut self, other: Option<&Self>) {
|
||||
let Some(other) = other else { return };
|
||||
match (self, other) {
|
||||
(serde_json::Value::Object(this), serde_json::Value::Object(other)) => {
|
||||
for (k, v) in other {
|
||||
if let Some(existing) = this.get_mut(k) {
|
||||
existing.merge_from(other.get(k));
|
||||
} else {
|
||||
this.insert(k.clone(), v.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
(this, other) => *this = other.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: MergeFrom + Clone> MergeFrom for Rc<T> {
|
||||
fn merge_from(&mut self, other: Option<&Self>) {
|
||||
let Some(other) = other else { return };
|
||||
let mut this: T = self.as_ref().clone();
|
||||
this.merge_from(Some(other.as_ref()));
|
||||
*self = Rc::new(this)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
mod base_keymap_setting;
|
||||
mod editable_setting_control;
|
||||
mod keymap_file;
|
||||
pub mod merge_from;
|
||||
mod settings_content;
|
||||
mod settings_file;
|
||||
mod settings_json;
|
||||
@@ -27,8 +28,7 @@ pub use settings_store::{
|
||||
InvalidSettingsError, LocalSettingsKind, Settings, SettingsKey, SettingsLocation, SettingsStore,
|
||||
};
|
||||
pub use settings_ui_core::*;
|
||||
// Re-export the derive macro
|
||||
pub use settings_ui_macros::{SettingsKey, SettingsUi};
|
||||
|
||||
pub use vscode_import::{VsCodeSettings, VsCodeSettingsSource};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
|
||||
@@ -22,15 +22,16 @@ use release_channel::ReleaseChannel;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::skip_serializing_none;
|
||||
use settings_macros::MergeFrom;
|
||||
use std::collections::BTreeSet;
|
||||
use std::env;
|
||||
use std::sync::Arc;
|
||||
pub use util::serde::default_true;
|
||||
|
||||
use crate::ActiveSettingsProfileName;
|
||||
use crate::{ActiveSettingsProfileName, merge_from};
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, PartialEq, Default, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, PartialEq, Default, Clone, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct SettingsContent {
|
||||
#[serde(flatten)]
|
||||
pub project: ProjectSettingsContent,
|
||||
@@ -153,7 +154,7 @@ pub struct SettingsContent {
|
||||
/// Whether to disable all AI features in Zed.
|
||||
///
|
||||
/// Default: false
|
||||
pub disable_ai: Option<bool>,
|
||||
pub disable_ai: Option<SaturatingBool>,
|
||||
|
||||
/// Settings related to Vim mode in Zed.
|
||||
pub vim: Option<VimSettingsContent>,
|
||||
@@ -166,14 +167,14 @@ impl SettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct ServerSettingsContent {
|
||||
#[serde(flatten)]
|
||||
pub project: ProjectSettingsContent,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct UserSettingsContent {
|
||||
#[serde(flatten)]
|
||||
pub content: Box<SettingsContent>,
|
||||
@@ -225,7 +226,9 @@ impl UserSettingsContent {
|
||||
/// Base key bindings scheme. Base keymaps can be overridden with user keymaps.
|
||||
///
|
||||
/// Default: VSCode
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Default)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default,
|
||||
)]
|
||||
pub enum BaseKeymapContent {
|
||||
#[default]
|
||||
VSCode,
|
||||
@@ -239,7 +242,7 @@ pub enum BaseKeymapContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, Debug)]
|
||||
#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
|
||||
pub struct TitleBarSettingsContent {
|
||||
/// Controls when the title bar is visible: "always" | "never" | "hide_in_full_screen".
|
||||
///
|
||||
@@ -275,7 +278,7 @@ pub struct TitleBarSettingsContent {
|
||||
pub show_menus: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, JsonSchema, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum TitleBarVisibility {
|
||||
Always,
|
||||
@@ -285,7 +288,7 @@ pub enum TitleBarVisibility {
|
||||
|
||||
/// Configuration of audio in Zed.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, Debug)]
|
||||
#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
|
||||
pub struct AudioSettingsContent {
|
||||
/// Opt into the new audio system.
|
||||
#[serde(rename = "experimental.rodio_audio", default)]
|
||||
@@ -307,7 +310,7 @@ pub struct AudioSettingsContent {
|
||||
|
||||
/// Control what info is collected by Zed.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Debug)]
|
||||
#[derive(Default, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Debug, MergeFrom)]
|
||||
pub struct TelemetrySettingsContent {
|
||||
/// Send debug info like crash reports.
|
||||
///
|
||||
@@ -320,7 +323,7 @@ pub struct TelemetrySettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Clone)]
|
||||
#[derive(Default, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Clone, MergeFrom)]
|
||||
pub struct DebuggerSettingsContent {
|
||||
/// Determines the stepping granularity.
|
||||
///
|
||||
@@ -353,7 +356,9 @@ pub struct DebuggerSettingsContent {
|
||||
}
|
||||
|
||||
/// The granularity of one 'step' in the stepping requests `next`, `stepIn`, `stepOut`, and `stepBack`.
|
||||
#[derive(PartialEq, Eq, Debug, Hash, Clone, Copy, Deserialize, Serialize, JsonSchema)]
|
||||
#[derive(
|
||||
PartialEq, Eq, Debug, Hash, Clone, Copy, Deserialize, Serialize, JsonSchema, MergeFrom,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum SteppingGranularity {
|
||||
/// The step should allow the program to run until the current statement has finished executing.
|
||||
@@ -366,7 +371,7 @@ pub enum SteppingGranularity {
|
||||
Instruction,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum DockPosition {
|
||||
Left,
|
||||
@@ -376,7 +381,7 @@ pub enum DockPosition {
|
||||
|
||||
/// Settings for slash commands.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
pub struct SlashCommandSettings {
|
||||
/// Settings for the `/cargo-workspace` slash command.
|
||||
pub cargo_workspace: Option<CargoWorkspaceCommandSettings>,
|
||||
@@ -384,7 +389,7 @@ pub struct SlashCommandSettings {
|
||||
|
||||
/// Settings for the `/cargo-workspace` slash command.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
pub struct CargoWorkspaceCommandSettings {
|
||||
/// Whether `/cargo-workspace` is enabled.
|
||||
pub enabled: Option<bool>,
|
||||
@@ -392,7 +397,7 @@ pub struct CargoWorkspaceCommandSettings {
|
||||
|
||||
/// Configuration of voice calls in Zed.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, Debug)]
|
||||
#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
|
||||
pub struct CallSettingsContent {
|
||||
/// Whether the microphone should be muted when joining a channel or a call.
|
||||
///
|
||||
@@ -406,7 +411,7 @@ pub struct CallSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Deserialize, Serialize, PartialEq, Debug, Default, Clone, JsonSchema)]
|
||||
#[derive(Deserialize, Serialize, PartialEq, Debug, Default, Clone, JsonSchema, MergeFrom)]
|
||||
pub struct ExtensionSettingsContent {
|
||||
/// The extensions that should be automatically installed by Zed.
|
||||
///
|
||||
@@ -421,7 +426,7 @@ pub struct ExtensionSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, Debug)]
|
||||
#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
|
||||
pub struct GitPanelSettingsContent {
|
||||
/// Whether to show the panel button in the status bar.
|
||||
///
|
||||
@@ -462,7 +467,9 @@ pub struct GitPanelSettingsContent {
|
||||
pub collapse_untracked_diff: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Default, Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(
|
||||
Default, Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum StatusStyle {
|
||||
#[default]
|
||||
@@ -471,13 +478,13 @@ pub enum StatusStyle {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
pub struct ScrollbarSettings {
|
||||
pub show: Option<ShowScrollbar>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
|
||||
pub struct NotificationPanelSettingsContent {
|
||||
/// Whether to show the panel button in the status bar.
|
||||
///
|
||||
@@ -494,7 +501,7 @@ pub struct NotificationPanelSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
|
||||
pub struct PanelSettingsContent {
|
||||
/// Whether to show the panel button in the status bar.
|
||||
///
|
||||
@@ -511,7 +518,7 @@ pub struct PanelSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
|
||||
pub struct MessageEditorSettings {
|
||||
/// Whether to automatically replace emoji shortcodes with emoji characters.
|
||||
/// For example: typing `:wave:` gets replaced with `👋`.
|
||||
@@ -521,7 +528,7 @@ pub struct MessageEditorSettings {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
|
||||
pub struct FileFinderSettingsContent {
|
||||
/// Whether to show file icons in the file finder.
|
||||
///
|
||||
@@ -549,10 +556,12 @@ pub struct FileFinderSettingsContent {
|
||||
///
|
||||
/// Default: None
|
||||
/// todo() -> Change this type to an enum
|
||||
pub include_ignored: Option<Option<bool>>,
|
||||
pub include_ignored: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(
|
||||
Debug, PartialEq, Eq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema, MergeFrom,
|
||||
)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum FileFinderWidthContent {
|
||||
#[default]
|
||||
@@ -564,7 +573,7 @@ pub enum FileFinderWidthContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Debug, JsonSchema)]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Debug, JsonSchema, MergeFrom)]
|
||||
pub struct VimSettingsContent {
|
||||
pub default_mode: Option<ModeContent>,
|
||||
pub toggle_relative_line_numbers: Option<bool>,
|
||||
@@ -575,7 +584,7 @@ pub struct VimSettingsContent {
|
||||
pub cursor_shape: Option<CursorShapeSettings>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq, Debug)]
|
||||
#[derive(Copy, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ModeContent {
|
||||
#[default]
|
||||
@@ -585,7 +594,7 @@ pub enum ModeContent {
|
||||
}
|
||||
|
||||
/// Controls when to use system clipboard.
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum UseSystemClipboard {
|
||||
/// Don't use system clipboard.
|
||||
@@ -598,7 +607,7 @@ pub enum UseSystemClipboard {
|
||||
|
||||
/// The settings for cursor shape.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
pub struct CursorShapeSettings {
|
||||
/// Cursor shape for the normal mode.
|
||||
///
|
||||
@@ -620,7 +629,7 @@ pub struct CursorShapeSettings {
|
||||
|
||||
/// Settings specific to journaling
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
pub struct JournalSettingsContent {
|
||||
/// The path of the directory where journal entries are stored.
|
||||
///
|
||||
@@ -632,7 +641,7 @@ pub struct JournalSettingsContent {
|
||||
pub hour_format: Option<HourFormat>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum HourFormat {
|
||||
#[default]
|
||||
@@ -641,7 +650,7 @@ pub enum HourFormat {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
|
||||
pub struct OutlinePanelSettingsContent {
|
||||
/// Whether to show the outline panel button in the status bar.
|
||||
///
|
||||
@@ -695,14 +704,14 @@ pub struct OutlinePanelSettingsContent {
|
||||
pub expand_outlines_with_depth: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Copy, PartialEq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, Copy, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum DockSide {
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize, Serialize, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize, Serialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ShowIndentGuides {
|
||||
Always,
|
||||
@@ -710,13 +719,13 @@ pub enum ShowIndentGuides {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
pub struct IndentGuidesSettingsContent {
|
||||
/// When to show the scrollbar in the outline panel.
|
||||
pub show: Option<ShowIndentGuides>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Default, PartialEq, Debug, JsonSchema, Deserialize, Serialize)]
|
||||
#[derive(Clone, Copy, Default, PartialEq, Debug, JsonSchema, MergeFrom, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum LineIndicatorFormat {
|
||||
Short,
|
||||
@@ -726,7 +735,7 @@ pub enum LineIndicatorFormat {
|
||||
|
||||
/// The settings for the image viewer.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Default, PartialEq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, Default, PartialEq)]
|
||||
pub struct ImageViewerSettingsContent {
|
||||
/// The unit to use for displaying image file sizes.
|
||||
///
|
||||
@@ -735,7 +744,7 @@ pub struct ImageViewerSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, Default, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, Default, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ImageFileSizeUnit {
|
||||
/// Displays file size in binary units (e.g., KiB, MiB).
|
||||
@@ -746,7 +755,7 @@ pub enum ImageFileSizeUnit {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
pub struct RemoteSettingsContent {
|
||||
pub ssh_connections: Option<Vec<SshConnection>>,
|
||||
pub wsl_connections: Option<Vec<WslConnection>>,
|
||||
@@ -754,7 +763,7 @@ pub struct RemoteSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
|
||||
pub struct SshConnection {
|
||||
pub host: SharedString,
|
||||
pub username: Option<String>,
|
||||
@@ -774,7 +783,7 @@ pub struct SshConnection {
|
||||
pub port_forwards: Option<Vec<SshPortForwardOption>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Serialize, Deserialize, PartialEq, JsonSchema, Debug)]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom, Debug)]
|
||||
pub struct WslConnection {
|
||||
pub distro_name: SharedString,
|
||||
pub user: Option<String>,
|
||||
@@ -791,7 +800,7 @@ pub struct SshProject {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize, JsonSchema)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize, JsonSchema, MergeFrom)]
|
||||
pub struct SshPortForwardOption {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub local_host: Option<String>,
|
||||
@@ -803,7 +812,7 @@ pub struct SshPortForwardOption {
|
||||
|
||||
/// Settings for configuring REPL display and behavior.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct ReplSettingsContent {
|
||||
/// Maximum number of lines to keep in REPL's scrollback buffer.
|
||||
/// Clamped with [4, 256] range.
|
||||
@@ -816,3 +825,42 @@ pub struct ReplSettingsContent {
|
||||
/// Default: 128
|
||||
pub max_columns: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct ExtendingVec<T>(pub Vec<T>);
|
||||
|
||||
impl<T> Into<Vec<T>> for ExtendingVec<T> {
|
||||
fn into(self) -> Vec<T> {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
impl<T> From<Vec<T>> for ExtendingVec<T> {
|
||||
fn from(vec: Vec<T>) -> Self {
|
||||
ExtendingVec(vec)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> merge_from::MergeFrom for ExtendingVec<T> {
|
||||
fn merge_from(&mut self, other: Option<&Self>) {
|
||||
if let Some(other) = other {
|
||||
self.0.extend_from_slice(other.0.as_slice());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Copy, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct SaturatingBool(pub bool);
|
||||
|
||||
impl From<bool> for SaturatingBool {
|
||||
fn from(value: bool) -> Self {
|
||||
SaturatingBool(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl merge_from::MergeFrom for SaturatingBool {
|
||||
fn merge_from(&mut self, other: Option<&Self>) {
|
||||
if let Some(other) = other {
|
||||
self.0 |= other.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,13 @@ use gpui::SharedString;
|
||||
use schemars::{JsonSchema, json_schema};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::skip_serializing_none;
|
||||
use settings_macros::MergeFrom;
|
||||
use std::{borrow::Cow, path::PathBuf, sync::Arc};
|
||||
|
||||
use crate::DockPosition;
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, PartialEq, Serialize, Deserialize, JsonSchema, Debug, Default)]
|
||||
#[derive(Clone, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, Default)]
|
||||
pub struct AgentSettingsContent {
|
||||
/// Whether the Agent is enabled.
|
||||
///
|
||||
@@ -168,7 +169,7 @@ impl AgentSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct AgentProfileContent {
|
||||
pub name: Arc<str>,
|
||||
#[serde(default)]
|
||||
@@ -180,12 +181,12 @@ pub struct AgentProfileContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, PartialEq, Clone, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, PartialEq, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct ContextServerPresetContent {
|
||||
pub tools: IndexMap<Arc<str>, bool>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum DefaultAgentView {
|
||||
#[default]
|
||||
@@ -193,7 +194,7 @@ pub enum DefaultAgentView {
|
||||
TextThread,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum NotifyWhenAgentWaiting {
|
||||
#[default]
|
||||
@@ -203,13 +204,13 @@ pub enum NotifyWhenAgentWaiting {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
pub struct LanguageModelSelection {
|
||||
pub provider: LanguageModelProviderSetting,
|
||||
pub model: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Default)]
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Default)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum CompletionMode {
|
||||
#[default]
|
||||
@@ -219,14 +220,14 @@ pub enum CompletionMode {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
pub struct LanguageModelParameters {
|
||||
pub provider: Option<LanguageModelProviderSetting>,
|
||||
pub model: Option<SharedString>,
|
||||
pub temperature: Option<f32>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, MergeFrom)]
|
||||
pub struct LanguageModelProviderSetting(pub String);
|
||||
|
||||
impl JsonSchema for LanguageModelProviderSetting {
|
||||
@@ -277,7 +278,7 @@ impl From<&str> for LanguageModelProviderSetting {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, PartialEq, Deserialize, Serialize, Clone, JsonSchema, Debug)]
|
||||
#[derive(Default, PartialEq, Deserialize, Serialize, Clone, JsonSchema, MergeFrom, Debug)]
|
||||
pub struct AllAgentServersSettings {
|
||||
pub gemini: Option<BuiltinAgentServerSettings>,
|
||||
pub claude: Option<BuiltinAgentServerSettings>,
|
||||
@@ -288,7 +289,7 @@ pub struct AllAgentServersSettings {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Deserialize, Serialize, Clone, JsonSchema, Debug, PartialEq)]
|
||||
#[derive(Default, Deserialize, Serialize, Clone, JsonSchema, MergeFrom, Debug, PartialEq)]
|
||||
pub struct BuiltinAgentServerSettings {
|
||||
/// Absolute path to a binary to be used when launching this agent.
|
||||
///
|
||||
@@ -320,7 +321,7 @@ pub struct BuiltinAgentServerSettings {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Deserialize, Serialize, Clone, JsonSchema, Debug, PartialEq)]
|
||||
#[derive(Deserialize, Serialize, Clone, JsonSchema, MergeFrom, Debug, PartialEq)]
|
||||
pub struct CustomAgentServerSettings {
|
||||
#[serde(rename = "command")]
|
||||
pub path: PathBuf,
|
||||
|
||||
@@ -4,11 +4,12 @@ use collections::HashMap;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::skip_serializing_none;
|
||||
use settings_macros::MergeFrom;
|
||||
|
||||
use crate::{DiagnosticSeverityContent, ShowScrollbar};
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct EditorSettingsContent {
|
||||
/// Whether the cursor blinks in the editor.
|
||||
///
|
||||
@@ -194,7 +195,7 @@ pub struct EditorSettingsContent {
|
||||
|
||||
// Status bar related settings
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
pub struct StatusBarContent {
|
||||
/// Whether to display the active language button in the status bar.
|
||||
///
|
||||
@@ -208,7 +209,7 @@ pub struct StatusBarContent {
|
||||
|
||||
// Toolbar related settings
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
pub struct ToolbarContent {
|
||||
/// Whether to display breadcrumbs in the editor toolbar.
|
||||
///
|
||||
@@ -235,7 +236,7 @@ pub struct ToolbarContent {
|
||||
|
||||
/// Scrollbar related settings
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Default)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Default)]
|
||||
pub struct ScrollbarContent {
|
||||
/// When to show the scrollbar in the editor.
|
||||
///
|
||||
@@ -271,7 +272,7 @@ pub struct ScrollbarContent {
|
||||
|
||||
/// Minimap related settings
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Default, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Clone, Default, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
pub struct MinimapContent {
|
||||
/// When to show the minimap in the editor.
|
||||
///
|
||||
@@ -296,7 +297,7 @@ pub struct MinimapContent {
|
||||
/// How to highlight the current line in the minimap.
|
||||
///
|
||||
/// Default: inherits editor line highlights setting
|
||||
pub current_line_highlight: Option<Option<CurrentLineHighlight>>,
|
||||
pub current_line_highlight: Option<CurrentLineHighlight>,
|
||||
|
||||
/// Maximum number of columns to display in the minimap.
|
||||
///
|
||||
@@ -306,7 +307,7 @@ pub struct MinimapContent {
|
||||
|
||||
/// Forcefully enable or disable the scrollbar for each axis
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Default)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Default)]
|
||||
pub struct ScrollbarAxesContent {
|
||||
/// When false, forcefully disables the horizontal scrollbar. Otherwise, obey other settings.
|
||||
///
|
||||
@@ -321,7 +322,7 @@ pub struct ScrollbarAxesContent {
|
||||
|
||||
/// Gutter related settings
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
pub struct GutterContent {
|
||||
/// Whether to show line numbers in the gutter.
|
||||
///
|
||||
@@ -346,7 +347,9 @@ pub struct GutterContent {
|
||||
}
|
||||
|
||||
/// How to render LSP `textDocument/documentColor` colors in the editor.
|
||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum DocumentColorsRenderMode {
|
||||
/// Do not query and render document colors.
|
||||
@@ -360,7 +363,7 @@ pub enum DocumentColorsRenderMode {
|
||||
Background,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum CurrentLineHighlight {
|
||||
// Don't highlight the current line.
|
||||
@@ -374,7 +377,7 @@ pub enum CurrentLineHighlight {
|
||||
}
|
||||
|
||||
/// When to populate a new search's query based on the text under the cursor.
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum SeedQuerySetting {
|
||||
/// Always populate the search query with the word under the cursor.
|
||||
@@ -386,7 +389,9 @@ pub enum SeedQuerySetting {
|
||||
}
|
||||
|
||||
/// What to do when multibuffer is double clicked in some of its excerpts (parts of singleton buffers).
|
||||
#[derive(Default, Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(
|
||||
Default, Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum DoubleClickInMultibuffer {
|
||||
/// Behave as a regular buffer and select the whole word.
|
||||
@@ -400,7 +405,9 @@ pub enum DoubleClickInMultibuffer {
|
||||
/// When to show the minimap thumb.
|
||||
///
|
||||
/// Default: always
|
||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum MinimapThumb {
|
||||
/// Show the minimap thumb only when the mouse is hovering over the minimap.
|
||||
@@ -413,7 +420,9 @@ pub enum MinimapThumb {
|
||||
/// Defines the border style for the minimap's scrollbar thumb.
|
||||
///
|
||||
/// Default: left_open
|
||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum MinimapThumbBorder {
|
||||
/// Displays a border on all sides of the thumb.
|
||||
@@ -432,7 +441,7 @@ pub enum MinimapThumbBorder {
|
||||
/// Which diagnostic indicators to show in the scrollbar.
|
||||
///
|
||||
/// Default: all
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum ScrollbarDiagnostics {
|
||||
/// Show all diagnostic levels: hint, information, warnings, error.
|
||||
@@ -450,7 +459,7 @@ pub enum ScrollbarDiagnostics {
|
||||
/// The key to use for adding multiple cursors
|
||||
///
|
||||
/// Default: alt
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum MultiCursorModifier {
|
||||
Alt,
|
||||
@@ -461,7 +470,7 @@ pub enum MultiCursorModifier {
|
||||
/// Whether the editor will scroll beyond the last line.
|
||||
///
|
||||
/// Default: one_page
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ScrollBeyondLastLine {
|
||||
/// The editor will not scroll beyond the last line.
|
||||
@@ -475,7 +484,9 @@ pub enum ScrollBeyondLastLine {
|
||||
}
|
||||
|
||||
/// The shape of a selection cursor.
|
||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum CursorShape {
|
||||
/// A vertical bar
|
||||
@@ -490,7 +501,9 @@ pub enum CursorShape {
|
||||
}
|
||||
|
||||
/// What to do when go to definition yields no results.
|
||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GoToDefinitionFallback {
|
||||
/// Disables the fallback.
|
||||
@@ -503,7 +516,9 @@ pub enum GoToDefinitionFallback {
|
||||
/// Determines when the mouse cursor should be hidden in an editor or input box.
|
||||
///
|
||||
/// Default: on_typing_and_movement
|
||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum HideMouseMode {
|
||||
/// Never hide the mouse cursor
|
||||
@@ -518,7 +533,9 @@ pub enum HideMouseMode {
|
||||
/// Determines how snippets are sorted relative to other completion items.
|
||||
///
|
||||
/// Default: inline
|
||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum SnippetSortOrder {
|
||||
/// Place snippets at the top of the completion list
|
||||
@@ -534,7 +551,7 @@ pub enum SnippetSortOrder {
|
||||
|
||||
/// Default options for buffer and project search items.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Default, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Clone, Default, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
pub struct SearchSettingsContent {
|
||||
/// Whether to show the project search button in the status bar.
|
||||
pub button: Option<bool>,
|
||||
@@ -545,7 +562,7 @@ pub struct SearchSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct JupyterContent {
|
||||
/// Whether the Jupyter feature is enabled.
|
||||
@@ -561,7 +578,7 @@ pub struct JupyterContent {
|
||||
|
||||
/// Whether to allow drag and drop text selection in buffer.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Default, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Clone, Default, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
pub struct DragAndDropSelectionContent {
|
||||
/// When true, enables drag and drop text selection in buffer.
|
||||
///
|
||||
@@ -577,7 +594,9 @@ pub struct DragAndDropSelectionContent {
|
||||
/// When to show the minimap in the editor.
|
||||
///
|
||||
/// Default: never
|
||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ShowMinimap {
|
||||
/// Follow the visibility of the scrollbar.
|
||||
@@ -592,7 +611,9 @@ pub enum ShowMinimap {
|
||||
/// Where to show the minimap in the editor.
|
||||
///
|
||||
/// Default: all_editors
|
||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum DisplayIn {
|
||||
/// Show on all open editors.
|
||||
|
||||
@@ -8,10 +8,10 @@ use serde::{
|
||||
de::{self, IntoDeserializer, MapAccess, SeqAccess, Visitor},
|
||||
};
|
||||
use serde_with::skip_serializing_none;
|
||||
use settings_macros::MergeFrom;
|
||||
use std::sync::Arc;
|
||||
use util::schemars::replace_subschema;
|
||||
|
||||
use crate::ParameterizedJsonSchema;
|
||||
use crate::{ExtendingVec, merge_from};
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
@@ -31,12 +31,50 @@ pub struct AllLanguageSettingsContent {
|
||||
/// Settings for associating file extensions and filenames
|
||||
/// with languages.
|
||||
#[serde(default)]
|
||||
pub file_types: HashMap<Arc<str>, Vec<String>>,
|
||||
pub file_types: HashMap<Arc<str>, ExtendingVec<String>>,
|
||||
}
|
||||
|
||||
fn merge_option<T: merge_from::MergeFrom + Clone>(this: &mut Option<T>, other: Option<&T>) {
|
||||
let Some(other) = other else { return };
|
||||
if let Some(this) = this {
|
||||
this.merge_from(Some(other));
|
||||
} else {
|
||||
this.replace(other.clone());
|
||||
}
|
||||
}
|
||||
|
||||
impl merge_from::MergeFrom for AllLanguageSettingsContent {
|
||||
fn merge_from(&mut self, other: Option<&Self>) {
|
||||
let Some(other) = other else { return };
|
||||
self.file_types.merge_from(Some(&other.file_types));
|
||||
merge_option(&mut self.features, other.features.as_ref());
|
||||
merge_option(&mut self.edit_predictions, other.edit_predictions.as_ref());
|
||||
|
||||
// A user's global settings override the default global settings and
|
||||
// all default language-specific settings.
|
||||
//
|
||||
self.defaults.merge_from(Some(&other.defaults));
|
||||
for language_settings in self.languages.0.values_mut() {
|
||||
language_settings.merge_from(Some(&other.defaults));
|
||||
}
|
||||
|
||||
// A user's language-specific settings override default language-specific settings.
|
||||
for (language_name, user_language_settings) in &other.languages.0 {
|
||||
if let Some(existing) = self.languages.0.get_mut(language_name) {
|
||||
existing.merge_from(Some(&user_language_settings));
|
||||
} else {
|
||||
let mut new_settings = self.defaults.clone();
|
||||
new_settings.merge_from(Some(&user_language_settings));
|
||||
|
||||
self.languages.0.insert(language_name.clone(), new_settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The settings for enabling/disabling features.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct FeaturesContent {
|
||||
/// Determines which edit prediction provider to use.
|
||||
@@ -44,7 +82,9 @@ pub struct FeaturesContent {
|
||||
}
|
||||
|
||||
/// The provider that supplies edit predictions.
|
||||
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum EditPredictionProvider {
|
||||
None,
|
||||
@@ -56,7 +96,7 @@ pub enum EditPredictionProvider {
|
||||
|
||||
/// The contents of the edit prediction settings.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
pub struct EditPredictionSettingsContent {
|
||||
/// A list of globs representing files that edit predictions should be disabled for.
|
||||
/// This list adds to a pre-existing, sensible default set of globs.
|
||||
@@ -73,7 +113,7 @@ pub struct EditPredictionSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
pub struct CopilotSettingsContent {
|
||||
/// HTTP/HTTPS proxy to use for Copilot.
|
||||
///
|
||||
@@ -90,7 +130,9 @@ pub struct CopilotSettingsContent {
|
||||
}
|
||||
|
||||
/// The mode in which edit predictions should be displayed.
|
||||
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum EditPredictionsMode {
|
||||
/// If provider supports it, display inline when holding modifier key (e.g., alt).
|
||||
@@ -104,7 +146,7 @@ pub enum EditPredictionsMode {
|
||||
}
|
||||
|
||||
/// Controls the soft-wrapping behavior in the editor.
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum SoftWrap {
|
||||
/// Prefer a single line generally, unless an overly long line is encountered.
|
||||
@@ -122,7 +164,7 @@ pub enum SoftWrap {
|
||||
|
||||
/// The settings for a particular language.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct LanguageSettingsContent {
|
||||
/// How many columns a tab should occupy.
|
||||
///
|
||||
@@ -289,7 +331,7 @@ pub struct LanguageSettingsContent {
|
||||
}
|
||||
|
||||
/// Controls how whitespace should be displayedin the editor.
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ShowWhitespaceSetting {
|
||||
/// Draw whitespace only for the selected text.
|
||||
@@ -310,7 +352,7 @@ pub enum ShowWhitespaceSetting {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
pub struct WhitespaceMap {
|
||||
pub space: Option<String>,
|
||||
pub tab: Option<String>,
|
||||
@@ -331,7 +373,7 @@ impl WhitespaceMap {
|
||||
}
|
||||
|
||||
/// The behavior of `editor::Rewrap`.
|
||||
#[derive(Debug, PartialEq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, PartialEq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum RewrapBehavior {
|
||||
/// Only rewrap within comments.
|
||||
@@ -344,7 +386,7 @@ pub enum RewrapBehavior {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct JsxTagAutoCloseSettingsContent {
|
||||
/// Enables or disables auto-closing of JSX tags.
|
||||
pub enabled: Option<bool>,
|
||||
@@ -352,7 +394,7 @@ pub struct JsxTagAutoCloseSettingsContent {
|
||||
|
||||
/// The settings for inlay hints.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Default, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Clone, Default, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
pub struct InlayHintSettingsContent {
|
||||
/// Global switch to toggle hints on and off.
|
||||
///
|
||||
@@ -434,7 +476,7 @@ impl InlayHintKind {
|
||||
|
||||
/// Controls how completions are processed for this language.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, Default)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom, Default)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct CompletionSettingsContent {
|
||||
/// Controls how words are completed.
|
||||
@@ -462,7 +504,7 @@ pub struct CompletionSettingsContent {
|
||||
pub lsp_insert_mode: Option<LspInsertMode>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum LspInsertMode {
|
||||
/// Replaces text before the cursor, using the `insert` range described in the LSP specification.
|
||||
@@ -478,7 +520,7 @@ pub enum LspInsertMode {
|
||||
}
|
||||
|
||||
/// Controls how document's words are completed.
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum WordsCompletionMode {
|
||||
/// Always fetch document's words for completions along with LSP completions.
|
||||
@@ -495,7 +537,7 @@ pub enum WordsCompletionMode {
|
||||
/// and configure default Prettier, used when no project-level Prettier installation is found.
|
||||
/// Prettier formatting is disabled by default.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct PrettierSettingsContent {
|
||||
/// Enables or disables formatting with Prettier for a given language.
|
||||
pub allowed: Option<bool>,
|
||||
@@ -515,7 +557,7 @@ pub struct PrettierSettingsContent {
|
||||
}
|
||||
|
||||
/// Controls the behavior of formatting files when they are saved.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, MergeFrom)]
|
||||
pub enum FormatOnSave {
|
||||
/// Files should be formatted on save.
|
||||
On,
|
||||
@@ -614,7 +656,7 @@ impl<'de> Deserialize<'de> for FormatOnSave {
|
||||
}
|
||||
|
||||
/// Controls which formatter should be used when formatting code.
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, MergeFrom)]
|
||||
pub enum SelectedFormatter {
|
||||
/// Format files using Zed's Prettier integration (if applicable),
|
||||
/// or falling back to formatting via language server.
|
||||
@@ -710,7 +752,7 @@ impl<'de> Deserialize<'de> for SelectedFormatter {
|
||||
}
|
||||
|
||||
/// Controls which formatters should be used when formatting code.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(untagged)]
|
||||
pub enum FormatterList {
|
||||
Single(Formatter),
|
||||
@@ -733,7 +775,7 @@ impl AsRef<[Formatter]> for FormatterList {
|
||||
}
|
||||
|
||||
/// Controls which formatter should be used when formatting code. If there are multiple formatters, they are executed in the order of declaration.
|
||||
#[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Formatter {
|
||||
/// Format code using the current language server.
|
||||
@@ -754,7 +796,7 @@ pub enum Formatter {
|
||||
|
||||
/// The settings for indent guides.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct IndentGuideSettingsContent {
|
||||
/// Whether to display indent guides in the editor.
|
||||
///
|
||||
@@ -780,7 +822,7 @@ pub struct IndentGuideSettingsContent {
|
||||
|
||||
/// The task settings for a particular language.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize, JsonSchema, MergeFrom)]
|
||||
pub struct LanguageTaskSettingsContent {
|
||||
/// Extra task variables to set for a particular language.
|
||||
#[serde(default)]
|
||||
@@ -796,37 +838,15 @@ pub struct LanguageTaskSettingsContent {
|
||||
pub prefer_lsp: Option<bool>,
|
||||
}
|
||||
|
||||
/// Map from language name to settings. Its `ParameterizedJsonSchema` allows only known language
|
||||
/// names in the keys.
|
||||
/// Map from language name to settings.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct LanguageToSettingsMap(pub HashMap<SharedString, LanguageSettingsContent>);
|
||||
|
||||
inventory::submit! {
|
||||
ParameterizedJsonSchema {
|
||||
add_and_get_ref: |generator, params, _cx| {
|
||||
let language_settings_content_ref = generator
|
||||
.subschema_for::<LanguageSettingsContent>()
|
||||
.to_value();
|
||||
replace_subschema::<LanguageToSettingsMap>(generator, || json_schema!({
|
||||
"type": "object",
|
||||
"properties": params
|
||||
.language_names
|
||||
.iter()
|
||||
.map(|name| {
|
||||
(
|
||||
name.clone(),
|
||||
language_settings_content_ref.clone(),
|
||||
)
|
||||
})
|
||||
.collect::<serde_json::Map<_, _>>()
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines how indent guides are colored.
|
||||
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(
|
||||
Default, Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum IndentGuideColoring {
|
||||
/// Do not render any lines for indent guides.
|
||||
@@ -839,7 +859,9 @@ pub enum IndentGuideColoring {
|
||||
}
|
||||
|
||||
/// Determines how indent guide backgrounds are colored.
|
||||
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(
|
||||
Default, Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum IndentGuideBackgroundColoring {
|
||||
/// Do not render any background for indent guides.
|
||||
|
||||
@@ -2,11 +2,12 @@ use collections::HashMap;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::skip_serializing_none;
|
||||
use settings_macros::MergeFrom;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
|
||||
pub struct AllLanguageModelSettingsContent {
|
||||
pub anthropic: Option<AnthropicSettingsContent>,
|
||||
pub bedrock: Option<AmazonBedrockSettingsContent>,
|
||||
@@ -25,14 +26,14 @@ pub struct AllLanguageModelSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
|
||||
pub struct AnthropicSettingsContent {
|
||||
pub api_url: Option<String>,
|
||||
pub available_models: Option<Vec<AnthropicAvailableModel>>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct AnthropicAvailableModel {
|
||||
/// The model's name in the Anthropic API. e.g. claude-3-5-sonnet-latest, claude-3-opus-20240229, etc
|
||||
pub name: String,
|
||||
@@ -53,7 +54,7 @@ pub struct AnthropicAvailableModel {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
|
||||
pub struct AmazonBedrockSettingsContent {
|
||||
pub available_models: Option<Vec<BedrockAvailableModel>>,
|
||||
pub endpoint_url: Option<String>,
|
||||
@@ -63,7 +64,7 @@ pub struct AmazonBedrockSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct BedrockAvailableModel {
|
||||
pub name: String,
|
||||
pub display_name: Option<String>,
|
||||
@@ -74,7 +75,7 @@ pub struct BedrockAvailableModel {
|
||||
pub mode: Option<ModelMode>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub enum BedrockAuthMethodContent {
|
||||
#[serde(rename = "named_profile")]
|
||||
NamedProfile,
|
||||
@@ -86,14 +87,14 @@ pub enum BedrockAuthMethodContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
|
||||
pub struct OllamaSettingsContent {
|
||||
pub api_url: Option<String>,
|
||||
pub available_models: Option<Vec<OllamaAvailableModel>>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct OllamaAvailableModel {
|
||||
/// The model name in the Ollama API (e.g. "llama3.2:latest")
|
||||
pub name: String,
|
||||
@@ -111,7 +112,7 @@ pub struct OllamaAvailableModel {
|
||||
pub supports_thinking: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Eq, PartialEq, JsonSchema)]
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Eq, PartialEq, JsonSchema, MergeFrom)]
|
||||
#[serde(untagged)]
|
||||
pub enum KeepAlive {
|
||||
/// Keep model alive for N seconds
|
||||
@@ -134,14 +135,14 @@ impl Default for KeepAlive {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
|
||||
pub struct LmStudioSettingsContent {
|
||||
pub api_url: Option<String>,
|
||||
pub available_models: Option<Vec<LmStudioAvailableModel>>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct LmStudioAvailableModel {
|
||||
pub name: String,
|
||||
pub display_name: Option<String>,
|
||||
@@ -151,14 +152,14 @@ pub struct LmStudioAvailableModel {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
|
||||
pub struct DeepseekSettingsContent {
|
||||
pub api_url: Option<String>,
|
||||
pub available_models: Option<Vec<DeepseekAvailableModel>>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct DeepseekAvailableModel {
|
||||
pub name: String,
|
||||
pub display_name: Option<String>,
|
||||
@@ -167,14 +168,14 @@ pub struct DeepseekAvailableModel {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
|
||||
pub struct MistralSettingsContent {
|
||||
pub api_url: Option<String>,
|
||||
pub available_models: Option<Vec<MistralAvailableModel>>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct MistralAvailableModel {
|
||||
pub name: String,
|
||||
pub display_name: Option<String>,
|
||||
@@ -187,14 +188,14 @@ pub struct MistralAvailableModel {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
|
||||
pub struct OpenAiSettingsContent {
|
||||
pub api_url: Option<String>,
|
||||
pub available_models: Option<Vec<OpenAiAvailableModel>>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct OpenAiAvailableModel {
|
||||
pub name: String,
|
||||
pub display_name: Option<String>,
|
||||
@@ -204,7 +205,7 @@ pub struct OpenAiAvailableModel {
|
||||
pub reasoning_effort: Option<OpenAiReasoningEffort>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, JsonSchema)]
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum OpenAiReasoningEffort {
|
||||
Minimal,
|
||||
@@ -214,14 +215,14 @@ pub enum OpenAiReasoningEffort {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
|
||||
pub struct OpenAiCompatibleSettingsContent {
|
||||
pub api_url: String,
|
||||
pub available_models: Vec<OpenAiCompatibleAvailableModel>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct OpenAiCompatibleAvailableModel {
|
||||
pub name: String,
|
||||
pub display_name: Option<String>,
|
||||
@@ -233,7 +234,7 @@ pub struct OpenAiCompatibleAvailableModel {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct OpenAiCompatibleModelCapabilities {
|
||||
pub tools: bool,
|
||||
pub images: bool,
|
||||
@@ -253,14 +254,14 @@ impl Default for OpenAiCompatibleModelCapabilities {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
|
||||
pub struct VercelSettingsContent {
|
||||
pub api_url: Option<String>,
|
||||
pub available_models: Option<Vec<VercelAvailableModel>>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct VercelAvailableModel {
|
||||
pub name: String,
|
||||
pub display_name: Option<String>,
|
||||
@@ -270,14 +271,14 @@ pub struct VercelAvailableModel {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
|
||||
pub struct GoogleSettingsContent {
|
||||
pub api_url: Option<String>,
|
||||
pub available_models: Option<Vec<GoogleAvailableModel>>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct GoogleAvailableModel {
|
||||
pub name: String,
|
||||
pub display_name: Option<String>,
|
||||
@@ -286,14 +287,14 @@ pub struct GoogleAvailableModel {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
|
||||
pub struct XAiSettingsContent {
|
||||
pub api_url: Option<String>,
|
||||
pub available_models: Option<Vec<XaiAvailableModel>>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct XaiAvailableModel {
|
||||
pub name: String,
|
||||
pub display_name: Option<String>,
|
||||
@@ -303,13 +304,13 @@ pub struct XaiAvailableModel {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
|
||||
pub struct ZedDotDevSettingsContent {
|
||||
pub available_models: Option<Vec<ZedDotDevAvailableModel>>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct ZedDotDevAvailableModel {
|
||||
/// The provider of the language model.
|
||||
pub provider: ZedDotDevAvailableProvider,
|
||||
@@ -336,7 +337,7 @@ pub struct ZedDotDevAvailableModel {
|
||||
pub mode: Option<ModelMode>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum ZedDotDevAvailableProvider {
|
||||
Anthropic,
|
||||
@@ -345,14 +346,14 @@ pub enum ZedDotDevAvailableProvider {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
|
||||
pub struct OpenRouterSettingsContent {
|
||||
pub api_url: Option<String>,
|
||||
pub available_models: Option<Vec<OpenRouterAvailableModel>>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct OpenRouterAvailableModel {
|
||||
pub name: String,
|
||||
pub display_name: Option<String>,
|
||||
@@ -366,7 +367,7 @@ pub struct OpenRouterAvailableModel {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct OpenRouterProvider {
|
||||
order: Option<Vec<String>>,
|
||||
#[serde(default = "default_true")]
|
||||
@@ -381,7 +382,7 @@ pub struct OpenRouterProvider {
|
||||
sort: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum DataCollection {
|
||||
Allow,
|
||||
@@ -400,14 +401,16 @@ fn default_true() -> bool {
|
||||
|
||||
/// Configuration for caching language model messages.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct LanguageModelCacheConfiguration {
|
||||
pub max_cache_anchors: usize,
|
||||
pub should_speculate: bool,
|
||||
pub min_total_token: u64,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom,
|
||||
)]
|
||||
#[serde(tag = "type", rename_all = "lowercase")]
|
||||
pub enum ModelMode {
|
||||
#[default]
|
||||
|
||||
@@ -4,12 +4,13 @@ use collections::{BTreeMap, HashMap};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::skip_serializing_none;
|
||||
use settings_macros::MergeFrom;
|
||||
use util::serde::default_true;
|
||||
|
||||
use crate::{AllLanguageSettingsContent, SlashCommandSettings};
|
||||
use crate::{AllLanguageSettingsContent, ExtendingVec, SlashCommandSettings};
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, PartialEq, Clone, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, PartialEq, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct ProjectSettingsContent {
|
||||
#[serde(flatten)]
|
||||
pub all_languages: AllLanguageSettingsContent,
|
||||
@@ -43,11 +44,11 @@ pub struct ProjectSettingsContent {
|
||||
pub slash_commands: Option<SlashCommandSettings>,
|
||||
|
||||
/// The list of custom Git hosting providers.
|
||||
pub git_hosting_providers: Option<Vec<GitHostingProviderConfig>>,
|
||||
pub git_hosting_providers: Option<ExtendingVec<GitHostingProviderConfig>>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct WorktreeSettingsContent {
|
||||
/// The displayed name of this project. If not set, the root directory name
|
||||
/// will be displayed.
|
||||
@@ -81,11 +82,11 @@ pub struct WorktreeSettingsContent {
|
||||
|
||||
/// Treat the files matching these globs as `.env` files.
|
||||
/// Default: ["**/.env*", "**/*.pem", "**/*.key", "**/*.cert", "**/*.crt", "**/secrets.yml"]
|
||||
pub private_files: Option<Vec<String>>,
|
||||
pub private_files: Option<ExtendingVec<String>>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, Hash)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom, Hash)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct LspSettings {
|
||||
pub binary: Option<BinarySettings>,
|
||||
@@ -112,7 +113,9 @@ impl Default for LspSettings {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, Hash)]
|
||||
#[derive(
|
||||
Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom, Hash,
|
||||
)]
|
||||
pub struct BinarySettings {
|
||||
pub path: Option<String>,
|
||||
pub arguments: Option<Vec<String>>,
|
||||
@@ -121,7 +124,9 @@ pub struct BinarySettings {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, Hash)]
|
||||
#[derive(
|
||||
Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom, Hash,
|
||||
)]
|
||||
pub struct FetchSettings {
|
||||
// Whether to consider pre-releases for fetching
|
||||
pub pre_release: Option<bool>,
|
||||
@@ -129,7 +134,7 @@ pub struct FetchSettings {
|
||||
|
||||
/// Common language server settings.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct GlobalLspSettingsContent {
|
||||
/// Whether to show the LSP servers button in the status bar.
|
||||
///
|
||||
@@ -138,7 +143,7 @@ pub struct GlobalLspSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct DapSettingsContent {
|
||||
pub binary: Option<String>,
|
||||
@@ -147,7 +152,9 @@ pub struct DapSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Default, Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(
|
||||
Default, Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, JsonSchema, MergeFrom,
|
||||
)]
|
||||
pub struct SessionSettingsContent {
|
||||
/// Whether or not to restore unsaved buffers on restart.
|
||||
///
|
||||
@@ -158,7 +165,7 @@ pub struct SessionSettingsContent {
|
||||
pub restore_unsaved_buffers: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Clone, PartialEq, Eq, JsonSchema, Debug)]
|
||||
#[derive(Deserialize, Serialize, Clone, PartialEq, Eq, JsonSchema, MergeFrom, Debug)]
|
||||
#[serde(tag = "source", rename_all = "snake_case")]
|
||||
pub enum ContextServerSettingsContent {
|
||||
Custom {
|
||||
@@ -198,7 +205,7 @@ impl ContextServerSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Deserialize, Serialize, Clone, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Deserialize, Serialize, Clone, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
pub struct ContextServerCommand {
|
||||
#[serde(rename = "command")]
|
||||
pub path: PathBuf,
|
||||
@@ -234,7 +241,7 @@ impl std::fmt::Debug for ContextServerCommand {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct GitSettings {
|
||||
/// Whether or not to show the git gutter.
|
||||
///
|
||||
@@ -259,7 +266,7 @@ pub struct GitSettings {
|
||||
pub hunk_style: Option<GitHunkStyleSetting>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GitGutterSetting {
|
||||
/// Show git gutter in tracked files.
|
||||
@@ -270,7 +277,7 @@ pub enum GitGutterSetting {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct InlineBlameSettings {
|
||||
/// Whether or not to show git blame data inline in
|
||||
@@ -299,7 +306,7 @@ pub struct InlineBlameSettings {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct BranchPickerSettingsContent {
|
||||
/// Whether to show author name as part of the commit information.
|
||||
@@ -308,7 +315,7 @@ pub struct BranchPickerSettingsContent {
|
||||
pub show_author_name: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Copy, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GitHunkStyleSetting {
|
||||
/// Show unstaged hunks with a filled background and staged hunks hollow.
|
||||
@@ -319,7 +326,7 @@ pub enum GitHunkStyleSetting {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct DiagnosticsSettingsContent {
|
||||
/// Whether to show the project diagnostics button in the status bar.
|
||||
pub button: Option<bool>,
|
||||
@@ -335,7 +342,7 @@ pub struct DiagnosticsSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
pub struct LspPullDiagnosticsSettingsContent {
|
||||
/// Whether to pull for diagnostics or not.
|
||||
///
|
||||
@@ -349,7 +356,7 @@ pub struct LspPullDiagnosticsSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, JsonSchema, Eq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom, Eq)]
|
||||
pub struct InlineDiagnosticsSettingsContent {
|
||||
/// Whether or not to show inline diagnostics
|
||||
///
|
||||
@@ -376,7 +383,7 @@ pub struct InlineDiagnosticsSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct NodeBinarySettings {
|
||||
/// The path to the Node binary.
|
||||
pub path: Option<String>,
|
||||
@@ -386,7 +393,7 @@ pub struct NodeBinarySettings {
|
||||
pub ignore_system_version: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum DirenvSettings {
|
||||
/// Load direnv configuration through a shell hook
|
||||
@@ -397,7 +404,17 @@ pub enum DirenvSettings {
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, JsonSchema,
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Ord,
|
||||
PartialOrd,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
JsonSchema,
|
||||
MergeFrom,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum DiagnosticSeverityContent {
|
||||
@@ -412,7 +429,7 @@ pub enum DiagnosticSeverityContent {
|
||||
|
||||
/// A custom Git hosting provider.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct GitHostingProviderConfig {
|
||||
/// The type of the provider.
|
||||
///
|
||||
@@ -426,7 +443,7 @@ pub struct GitHostingProviderConfig {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GitHostingProviderKind {
|
||||
Github,
|
||||
|
||||
@@ -5,11 +5,12 @@ use gpui::{AbsoluteLength, FontFeatures, SharedString, px};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::skip_serializing_none;
|
||||
use settings_macros::MergeFrom;
|
||||
|
||||
use crate::FontFamilyName;
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct TerminalSettingsContent {
|
||||
/// What shell to use when opening a terminal.
|
||||
///
|
||||
@@ -127,7 +128,7 @@ pub struct TerminalSettingsContent {
|
||||
}
|
||||
|
||||
/// Shell configuration to open the terminal with.
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Shell {
|
||||
/// Use the system's default terminal configuration in /etc/passwd
|
||||
@@ -146,7 +147,7 @@ pub enum Shell {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum WorkingDirectory {
|
||||
/// Use the current file's project directory. Will Fallback to the
|
||||
@@ -163,15 +164,15 @@ pub enum WorkingDirectory {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
pub struct ScrollbarSettingsContent {
|
||||
/// When to show the scrollbar in the terminal.
|
||||
///
|
||||
/// Default: inherits editor scrollbar settings
|
||||
pub show: Option<Option<ShowScrollbar>>,
|
||||
pub show: Option<ShowScrollbar>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, Default)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom, Default)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum TerminalLineHeight {
|
||||
/// Use a line height that's comfortable for reading, 1.618
|
||||
@@ -198,7 +199,7 @@ impl TerminalLineHeight {
|
||||
/// When to show the scrollbar.
|
||||
///
|
||||
/// Default: auto
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ShowScrollbar {
|
||||
/// Show the scrollbar if there's important information or
|
||||
@@ -212,7 +213,9 @@ pub enum ShowScrollbar {
|
||||
Never,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(
|
||||
Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum CursorShapeContent {
|
||||
/// Cursor is a block like `█`.
|
||||
@@ -226,7 +229,7 @@ pub enum CursorShapeContent {
|
||||
Hollow,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum TerminalBlink {
|
||||
/// Never blink the cursor, ignoring the terminal mode.
|
||||
@@ -238,7 +241,7 @@ pub enum TerminalBlink {
|
||||
On,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AlternateScroll {
|
||||
On,
|
||||
@@ -247,7 +250,7 @@ pub enum AlternateScroll {
|
||||
|
||||
// Toolbar related settings
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
pub struct TerminalToolbarContent {
|
||||
/// Whether to display the terminal title in breadcrumbs inside the terminal pane.
|
||||
/// Only shown if the terminal title is not empty.
|
||||
@@ -259,7 +262,7 @@ pub struct TerminalToolbarContent {
|
||||
pub breadcrumbs: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum VenvSettings {
|
||||
#[default]
|
||||
@@ -297,7 +300,7 @@ impl VenvSettings {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum TerminalDockPosition {
|
||||
Left,
|
||||
@@ -305,7 +308,7 @@ pub enum TerminalDockPosition {
|
||||
Right,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ActivateScript {
|
||||
#[default]
|
||||
|
||||
@@ -4,6 +4,7 @@ use schemars::{JsonSchema, JsonSchema_repr};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use serde_json::Value;
|
||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||
use settings_macros::MergeFrom;
|
||||
use std::sync::Arc;
|
||||
|
||||
use serde_with::skip_serializing_none;
|
||||
@@ -11,7 +12,7 @@ use serde_with::skip_serializing_none;
|
||||
/// Settings for rendering text in UI and text buffers.
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct ThemeSettingsContent {
|
||||
/// The default font size for text in the UI.
|
||||
#[serde(default)]
|
||||
@@ -53,7 +54,7 @@ pub struct ThemeSettingsContent {
|
||||
pub buffer_font_features: Option<FontFeatures>,
|
||||
/// The font size for the agent panel. Falls back to the UI font size if unset.
|
||||
#[serde(default)]
|
||||
pub agent_font_size: Option<Option<f32>>,
|
||||
pub agent_font_size: Option<f32>,
|
||||
/// The name of the Zed theme to use.
|
||||
#[serde(default)]
|
||||
pub theme: Option<ThemeSelection>,
|
||||
@@ -93,7 +94,7 @@ fn default_font_fallbacks() -> Option<FontFallbacks> {
|
||||
}
|
||||
|
||||
/// Represents the selection of a theme, which can be either static or dynamic.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
#[serde(untagged)]
|
||||
pub enum ThemeSelection {
|
||||
/// A static theme selection, represented by a single theme name.
|
||||
@@ -111,7 +112,7 @@ pub enum ThemeSelection {
|
||||
}
|
||||
|
||||
/// Represents the selection of an icon theme, which can be either static or dynamic.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
#[serde(untagged)]
|
||||
pub enum IconThemeSelection {
|
||||
/// A static icon theme selection, represented by a single icon theme name.
|
||||
@@ -134,7 +135,9 @@ pub enum IconThemeSelection {
|
||||
/// `Light` and `Dark` will select their respective themes.
|
||||
///
|
||||
/// `System` will select the theme based on the system's appearance.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(
|
||||
Debug, PartialEq, Eq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema, MergeFrom,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ThemeMode {
|
||||
/// Use the specified `light` theme.
|
||||
@@ -163,6 +166,7 @@ pub enum ThemeMode {
|
||||
Serialize,
|
||||
Deserialize,
|
||||
JsonSchema,
|
||||
MergeFrom,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum UiDensity {
|
||||
@@ -190,15 +194,14 @@ impl UiDensity {
|
||||
}
|
||||
}
|
||||
|
||||
/// Newtype for font family name. Its `ParameterizedJsonSchema` lists the font families known at
|
||||
/// runtime.
|
||||
/// Font family name.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
#[serde(transparent)]
|
||||
pub struct FontFamilyName(pub Arc<str>);
|
||||
|
||||
/// The buffer's line height.
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, JsonSchema, Default)]
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom, Default)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum BufferLineHeight {
|
||||
/// A less dense line height.
|
||||
@@ -226,7 +229,7 @@ where
|
||||
|
||||
/// The content of a serialized theme.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
#[serde(default)]
|
||||
pub struct ThemeStyleContent {
|
||||
#[serde(default, rename = "background.appearance")]
|
||||
@@ -249,31 +252,30 @@ pub struct ThemeStyleContent {
|
||||
pub syntax: IndexMap<String, HighlightStyleContent>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
pub struct AccentContent(pub Option<String>);
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
pub struct PlayerColorContent {
|
||||
pub cursor: Option<String>,
|
||||
pub background: Option<String>,
|
||||
pub selection: Option<String>,
|
||||
}
|
||||
|
||||
/// Newtype for a theme name. Its `ParameterizedJsonSchema` lists the theme names known at runtime.
|
||||
/// Theme name.
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
#[serde(transparent)]
|
||||
pub struct ThemeName(pub Arc<str>);
|
||||
|
||||
/// Newtype for a icon theme name. Its `ParameterizedJsonSchema` lists the icon theme names known at
|
||||
/// runtime.
|
||||
/// Icon Theme Name
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
#[serde(transparent)]
|
||||
pub struct IconThemeName(pub Arc<str>);
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
#[serde(default)]
|
||||
pub struct ThemeColorsContent {
|
||||
/// Border color. Used for most borders, is usually a high contrast color.
|
||||
@@ -778,7 +780,7 @@ pub struct ThemeColorsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
#[serde(default)]
|
||||
pub struct HighlightStyleContent {
|
||||
pub color: Option<String>,
|
||||
@@ -812,7 +814,7 @@ where
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
#[serde(default)]
|
||||
pub struct StatusColorsContent {
|
||||
/// Indicates some kind of conflict, like a file changed on disk while it was open, or
|
||||
@@ -958,7 +960,7 @@ pub struct StatusColorsContent {
|
||||
}
|
||||
|
||||
/// The background appearance of the window.
|
||||
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum WindowBackgroundContent {
|
||||
Opaque,
|
||||
@@ -976,7 +978,7 @@ impl Into<gpui::WindowBackgroundAppearance> for WindowBackgroundContent {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum FontStyleContent {
|
||||
Normal,
|
||||
@@ -994,7 +996,9 @@ impl From<FontStyleContent> for FontStyle {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize_repr, Deserialize_repr, JsonSchema_repr, PartialEq)]
|
||||
#[derive(
|
||||
Debug, Clone, Copy, Serialize_repr, Deserialize_repr, JsonSchema_repr, PartialEq, MergeFrom,
|
||||
)]
|
||||
#[repr(u16)]
|
||||
pub enum FontWeightContent {
|
||||
Thin = 100,
|
||||
|
||||
@@ -4,11 +4,12 @@ use collections::HashMap;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::skip_serializing_none;
|
||||
use settings_macros::MergeFrom;
|
||||
|
||||
use crate::{DockPosition, DockSide, ScrollbarSettingsContent, ShowIndentGuides};
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct WorkspaceSettingsContent {
|
||||
/// Active pane styling settings.
|
||||
pub active_pane_modifiers: Option<ActivePanelModifiers>,
|
||||
@@ -108,7 +109,7 @@ pub struct WorkspaceSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct ItemSettingsContent {
|
||||
/// Whether to show the Git file status on a tab item.
|
||||
///
|
||||
@@ -138,7 +139,7 @@ pub struct ItemSettingsContent {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct PreviewTabsSettingsContent {
|
||||
/// Whether to show opened editors as preview tabs.
|
||||
/// Preview tabs do not stay open, are reused until explicitly set to be kept open opened (via double-click or editing) and show file names in italic.
|
||||
@@ -155,7 +156,7 @@ pub struct PreviewTabsSettingsContent {
|
||||
pub enable_preview_from_code_navigation: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum ClosePosition {
|
||||
Left,
|
||||
@@ -163,7 +164,7 @@ pub enum ClosePosition {
|
||||
Right,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum ShowCloseButton {
|
||||
Always,
|
||||
@@ -172,7 +173,9 @@ pub enum ShowCloseButton {
|
||||
Hidden,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ShowDiagnostics {
|
||||
#[default]
|
||||
@@ -181,7 +184,7 @@ pub enum ShowDiagnostics {
|
||||
All,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ActivateOnClose {
|
||||
#[default]
|
||||
@@ -191,7 +194,7 @@ pub enum ActivateOnClose {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Copy, Clone, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct ActivePanelModifiers {
|
||||
/// Size of the border surrounding the active pane.
|
||||
@@ -209,7 +212,7 @@ pub struct ActivePanelModifiers {
|
||||
pub inactive_opacity: Option<f32>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum BottomDockLayout {
|
||||
/// Contained between the left and right docks
|
||||
@@ -223,7 +226,7 @@ pub enum BottomDockLayout {
|
||||
RightAligned,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum CloseWindowWhenNoItems {
|
||||
/// Match platform conventions by default, so "on" on macOS and "off" everywhere else
|
||||
@@ -245,7 +248,9 @@ impl CloseWindowWhenNoItems {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Default, Serialize, Deserialize, JsonSchema, Debug)]
|
||||
#[derive(
|
||||
Copy, Clone, PartialEq, Eq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum RestoreOnStartupBehavior {
|
||||
/// Always start with an empty editor
|
||||
@@ -258,7 +263,7 @@ pub enum RestoreOnStartupBehavior {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, PartialEq)]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
|
||||
pub struct TabBarSettingsContent {
|
||||
/// Whether or not to show the tab bar in the editor.
|
||||
///
|
||||
@@ -274,7 +279,7 @@ pub struct TabBarSettingsContent {
|
||||
pub show_tab_bar_buttons: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AutosaveSetting {
|
||||
/// Disable autosave.
|
||||
@@ -298,14 +303,14 @@ impl AutosaveSetting {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum PaneSplitDirectionHorizontal {
|
||||
Up,
|
||||
Down,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum PaneSplitDirectionVertical {
|
||||
Left,
|
||||
@@ -313,7 +318,7 @@ pub enum PaneSplitDirectionVertical {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct CenteredLayoutSettings {
|
||||
/// The relative width of the left padding of the central pane from the
|
||||
@@ -328,7 +333,7 @@ pub struct CenteredLayoutSettings {
|
||||
pub right_padding: Option<f32>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq, Debug)]
|
||||
#[derive(Copy, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum OnLastWindowClosed {
|
||||
/// Match platform conventions by default, so don't quit on macOS, and quit on other platforms
|
||||
@@ -348,7 +353,7 @@ impl OnLastWindowClosed {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, Debug)]
|
||||
#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
|
||||
pub struct ProjectPanelSettingsContent {
|
||||
/// Whether to show the project panel button in the status bar.
|
||||
///
|
||||
@@ -423,7 +428,9 @@ pub struct ProjectPanelSettingsContent {
|
||||
pub drag_and_drop: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ProjectPanelEntrySpacing {
|
||||
/// Comfortable spacing of entries.
|
||||
@@ -434,7 +441,7 @@ pub enum ProjectPanelEntrySpacing {
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
|
||||
pub struct ProjectPanelIndentGuidesSettings {
|
||||
pub show: Option<ShowIndentGuides>,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use anyhow::Result;
|
||||
use gpui::App;
|
||||
use gpui::SharedString;
|
||||
use serde::{Serialize, de::DeserializeOwned};
|
||||
use serde_json::Value;
|
||||
use std::{ops::Range, sync::LazyLock};
|
||||
@@ -10,16 +10,10 @@ use util::RangeExt;
|
||||
pub struct SettingsJsonSchemaParams<'a> {
|
||||
pub language_names: &'a [String],
|
||||
pub font_names: &'a [String],
|
||||
pub theme_names: &'a [SharedString],
|
||||
pub icon_theme_names: &'a [SharedString],
|
||||
}
|
||||
|
||||
/// Value registered which specifies JSON schemas that are generated at runtime.
|
||||
pub struct ParameterizedJsonSchema {
|
||||
pub add_and_get_ref:
|
||||
fn(&mut schemars::SchemaGenerator, &SettingsJsonSchemaParams, &App) -> schemars::Schema,
|
||||
}
|
||||
|
||||
inventory::collect!(ParameterizedJsonSchema);
|
||||
|
||||
pub fn update_value_in_json_text<'a>(
|
||||
text: &mut String,
|
||||
key_path: &mut Vec<&'a str>,
|
||||
|
||||
@@ -10,7 +10,7 @@ use futures::{
|
||||
use gpui::{App, AsyncApp, BorrowAppContext, Global, SharedString, Task, UpdateGlobal};
|
||||
|
||||
use paths::{EDITORCONFIG_NAME, local_settings_file_relative_path, task_file_name};
|
||||
use schemars::JsonSchema;
|
||||
use schemars::{JsonSchema, json_schema};
|
||||
use serde_json::Value;
|
||||
use smallvec::SmallVec;
|
||||
use std::{
|
||||
@@ -18,16 +18,23 @@ use std::{
|
||||
fmt::Debug,
|
||||
ops::Range,
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
str::{self, FromStr},
|
||||
sync::Arc,
|
||||
};
|
||||
use util::{ResultExt as _, schemars::DefaultDenyUnknownFields};
|
||||
use util::{
|
||||
ResultExt as _,
|
||||
schemars::{DefaultDenyUnknownFields, replace_subschema},
|
||||
};
|
||||
|
||||
pub type EditorconfigProperties = ec4rs::Properties;
|
||||
|
||||
use crate::{
|
||||
ActiveSettingsProfileName, ParameterizedJsonSchema, SettingsJsonSchemaParams, SettingsUiEntry,
|
||||
VsCodeSettings, WorktreeId, parse_json_with_comments, replace_value_in_json_text,
|
||||
ActiveSettingsProfileName, FontFamilyName, IconThemeName, LanguageSettingsContent,
|
||||
LanguageToSettingsMap, SettingsJsonSchemaParams, SettingsUiEntry, ThemeName, VsCodeSettings,
|
||||
WorktreeId,
|
||||
merge_from::MergeFrom,
|
||||
parse_json_with_comments, replace_value_in_json_text,
|
||||
settings_content::{
|
||||
ExtensionsSettingsContent, ProjectSettingsContent, ServerSettingsContent, SettingsContent,
|
||||
UserSettingsContent,
|
||||
@@ -58,15 +65,10 @@ pub trait Settings: 'static + Send + Sync + Sized {
|
||||
const PRESERVED_KEYS: Option<&'static [&'static str]> = None;
|
||||
|
||||
/// Read the value from default.json.
|
||||
///
|
||||
/// This function *should* panic if default values are missing,
|
||||
/// and you should add a default to default.json for documentation.
|
||||
fn from_defaults(content: &SettingsContent, cx: &mut App) -> Self;
|
||||
|
||||
/// Update the value based on the content from the current file.
|
||||
///
|
||||
/// This function *should not* panic if there are problems, as the
|
||||
/// content of user-provided settings files may be incomplete or invalid.
|
||||
fn refine(&mut self, content: &SettingsContent, cx: &mut App);
|
||||
fn from_settings(content: &SettingsContent, cx: &mut App) -> Self;
|
||||
|
||||
fn missing_default() -> anyhow::Error {
|
||||
anyhow::anyhow!("missing default for: {}", std::any::type_name::<Self>())
|
||||
@@ -140,12 +142,15 @@ pub struct SettingsLocation<'a> {
|
||||
/// A set of strongly-typed setting values defined via multiple config files.
|
||||
pub struct SettingsStore {
|
||||
setting_values: HashMap<TypeId, Box<dyn AnySettingValue>>,
|
||||
default_settings: Box<SettingsContent>,
|
||||
default_settings: Rc<SettingsContent>,
|
||||
user_settings: Option<UserSettingsContent>,
|
||||
global_settings: Option<Box<SettingsContent>>,
|
||||
|
||||
extension_settings: Option<Box<SettingsContent>>,
|
||||
server_settings: Option<Box<SettingsContent>>,
|
||||
|
||||
merged_settings: Rc<SettingsContent>,
|
||||
|
||||
local_settings: BTreeMap<(WorktreeId, Arc<Path>), SettingsContent>,
|
||||
raw_editorconfig_settings: BTreeMap<(WorktreeId, Arc<Path>), (String, Option<Editorconfig>)>,
|
||||
|
||||
@@ -193,8 +198,7 @@ struct SettingValue<T> {
|
||||
trait AnySettingValue: 'static + Send + Sync {
|
||||
fn setting_type_name(&self) -> &'static str;
|
||||
|
||||
fn from_default(&self, s: &SettingsContent, cx: &mut App) -> Box<dyn Any>;
|
||||
fn refine(&self, value: &mut dyn Any, s: &[&SettingsContent], cx: &mut App);
|
||||
fn from_settings(&self, s: &SettingsContent, cx: &mut App) -> Box<dyn Any>;
|
||||
|
||||
fn value_for_path(&self, path: Option<SettingsLocation>) -> &dyn Any;
|
||||
fn all_local_values(&self) -> Vec<(WorktreeId, Arc<Path>, &dyn Any)>;
|
||||
@@ -210,14 +214,17 @@ trait AnySettingValue: 'static + Send + Sync {
|
||||
impl SettingsStore {
|
||||
pub fn new(cx: &App, default_settings: &str) -> Self {
|
||||
let (setting_file_updates_tx, mut setting_file_updates_rx) = mpsc::unbounded();
|
||||
let default_settings = parse_json_with_comments(default_settings).unwrap();
|
||||
let default_settings: Rc<SettingsContent> =
|
||||
parse_json_with_comments(default_settings).unwrap();
|
||||
Self {
|
||||
setting_values: Default::default(),
|
||||
default_settings,
|
||||
default_settings: default_settings.clone(),
|
||||
global_settings: None,
|
||||
server_settings: None,
|
||||
user_settings: None,
|
||||
extension_settings: None,
|
||||
|
||||
merged_settings: default_settings,
|
||||
local_settings: BTreeMap::default(),
|
||||
raw_editorconfig_settings: BTreeMap::default(),
|
||||
setting_file_updates_tx,
|
||||
@@ -257,38 +264,7 @@ impl SettingsStore {
|
||||
global_value: None,
|
||||
local_values: Vec::new(),
|
||||
}));
|
||||
|
||||
let mut refinements = Vec::default();
|
||||
|
||||
if let Some(extension_settings) = self.extension_settings.as_deref() {
|
||||
refinements.push(extension_settings)
|
||||
}
|
||||
|
||||
if let Some(global_settings) = self.global_settings.as_deref() {
|
||||
refinements.push(global_settings)
|
||||
}
|
||||
|
||||
if let Some(user_settings) = self.user_settings.as_ref() {
|
||||
refinements.push(&user_settings.content);
|
||||
if let Some(release_channel) = user_settings.for_release_channel() {
|
||||
refinements.push(release_channel)
|
||||
}
|
||||
if let Some(os) = user_settings.for_os() {
|
||||
refinements.push(os)
|
||||
}
|
||||
if let Some(profile) = user_settings.for_profile(cx) {
|
||||
refinements.push(profile)
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(server_settings) = self.server_settings.as_ref() {
|
||||
refinements.push(server_settings)
|
||||
}
|
||||
let mut value = T::from_defaults(&self.default_settings, cx);
|
||||
for refinement in refinements {
|
||||
value.refine(refinement, cx)
|
||||
}
|
||||
|
||||
let value = T::from_settings(&self.merged_settings, cx);
|
||||
setting_value.set_global_value(Box::new(value));
|
||||
}
|
||||
|
||||
@@ -831,19 +807,56 @@ impl SettingsStore {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn json_schema(&self, schema_params: &SettingsJsonSchemaParams, cx: &App) -> Value {
|
||||
pub fn json_schema(&self, params: &SettingsJsonSchemaParams) -> Value {
|
||||
let mut generator = schemars::generate::SchemaSettings::draft2019_09()
|
||||
.with_transform(DefaultDenyUnknownFields)
|
||||
.into_generator();
|
||||
|
||||
let schema = UserSettingsContent::json_schema(&mut generator);
|
||||
UserSettingsContent::json_schema(&mut generator);
|
||||
|
||||
// add schemas which are determined at runtime
|
||||
for parameterized_json_schema in inventory::iter::<ParameterizedJsonSchema>() {
|
||||
(parameterized_json_schema.add_and_get_ref)(&mut generator, schema_params, cx);
|
||||
}
|
||||
let language_settings_content_ref = generator
|
||||
.subschema_for::<LanguageSettingsContent>()
|
||||
.to_value();
|
||||
replace_subschema::<LanguageToSettingsMap>(&mut generator, || {
|
||||
json_schema!({
|
||||
"type": "object",
|
||||
"properties": params
|
||||
.language_names
|
||||
.iter()
|
||||
.map(|name| {
|
||||
(
|
||||
name.clone(),
|
||||
language_settings_content_ref.clone(),
|
||||
)
|
||||
})
|
||||
.collect::<serde_json::Map<_, _>>()
|
||||
})
|
||||
});
|
||||
|
||||
schema.to_value()
|
||||
replace_subschema::<FontFamilyName>(&mut generator, || {
|
||||
json_schema!({
|
||||
"type": "string",
|
||||
"enum": params.font_names,
|
||||
})
|
||||
});
|
||||
|
||||
replace_subschema::<ThemeName>(&mut generator, || {
|
||||
json_schema!({
|
||||
"type": "string",
|
||||
"enum": params.theme_names,
|
||||
})
|
||||
});
|
||||
|
||||
replace_subschema::<IconThemeName>(&mut generator, || {
|
||||
json_schema!({
|
||||
"type": "string",
|
||||
"enum": params.icon_theme_names,
|
||||
})
|
||||
});
|
||||
|
||||
generator
|
||||
.root_schema_for::<UserSettingsContent>()
|
||||
.to_value()
|
||||
}
|
||||
|
||||
fn recompute_values(
|
||||
@@ -852,74 +865,62 @@ impl SettingsStore {
|
||||
cx: &mut App,
|
||||
) -> std::result::Result<(), InvalidSettingsError> {
|
||||
// Reload the global and local values for every setting.
|
||||
let mut project_settings_stack = Vec::<&SettingsContent>::new();
|
||||
let mut project_settings_stack = Vec::<SettingsContent>::new();
|
||||
let mut paths_stack = Vec::<Option<(WorktreeId, &Path)>>::new();
|
||||
|
||||
let mut refinements = Vec::default();
|
||||
|
||||
if let Some(extension_settings) = self.extension_settings.as_deref() {
|
||||
refinements.push(extension_settings)
|
||||
}
|
||||
|
||||
if let Some(global_settings) = self.global_settings.as_deref() {
|
||||
refinements.push(global_settings)
|
||||
}
|
||||
|
||||
if let Some(user_settings) = self.user_settings.as_ref() {
|
||||
refinements.push(&user_settings.content);
|
||||
if let Some(release_channel) = user_settings.for_release_channel() {
|
||||
refinements.push(release_channel)
|
||||
if changed_local_path.is_none() {
|
||||
let mut merged = self.default_settings.as_ref().clone();
|
||||
merged.merge_from(self.extension_settings.as_deref());
|
||||
merged.merge_from(self.global_settings.as_deref());
|
||||
if let Some(user_settings) = self.user_settings.as_ref() {
|
||||
merged.merge_from(Some(&user_settings.content));
|
||||
merged.merge_from(user_settings.for_release_channel());
|
||||
merged.merge_from(user_settings.for_os());
|
||||
merged.merge_from(user_settings.for_profile(cx));
|
||||
}
|
||||
if let Some(os) = user_settings.for_os() {
|
||||
refinements.push(os)
|
||||
}
|
||||
if let Some(profile) = user_settings.for_profile(cx) {
|
||||
refinements.push(profile)
|
||||
}
|
||||
}
|
||||
merged.merge_from(self.server_settings.as_deref());
|
||||
self.merged_settings = Rc::new(merged);
|
||||
|
||||
if let Some(server_settings) = self.server_settings.as_ref() {
|
||||
refinements.push(server_settings)
|
||||
}
|
||||
|
||||
for setting_value in self.setting_values.values_mut() {
|
||||
// If the global settings file changed, reload the global value for the field.
|
||||
if changed_local_path.is_none() {
|
||||
let mut value = setting_value.from_default(&self.default_settings, cx);
|
||||
setting_value.refine(value.as_mut(), &refinements, cx);
|
||||
for setting_value in self.setting_values.values_mut() {
|
||||
let value = setting_value.from_settings(&self.merged_settings, cx);
|
||||
setting_value.set_global_value(value);
|
||||
}
|
||||
}
|
||||
|
||||
// Reload the local values for the setting.
|
||||
paths_stack.clear();
|
||||
project_settings_stack.clear();
|
||||
for ((root_id, directory_path), local_settings) in &self.local_settings {
|
||||
// Build a stack of all of the local values for that setting.
|
||||
while let Some(prev_entry) = paths_stack.last() {
|
||||
if let Some((prev_root_id, prev_path)) = prev_entry
|
||||
&& (root_id != prev_root_id || !directory_path.starts_with(prev_path))
|
||||
{
|
||||
paths_stack.pop();
|
||||
project_settings_stack.pop();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
paths_stack.push(Some((*root_id, directory_path.as_ref())));
|
||||
project_settings_stack.push(local_settings);
|
||||
|
||||
// If a local settings file changed, then avoid recomputing local
|
||||
// settings for any path outside of that directory.
|
||||
if changed_local_path.is_some_and(|(changed_root_id, changed_local_path)| {
|
||||
*root_id != changed_root_id || !directory_path.starts_with(changed_local_path)
|
||||
}) {
|
||||
for ((root_id, directory_path), local_settings) in &self.local_settings {
|
||||
// Build a stack of all of the local values for that setting.
|
||||
while let Some(prev_entry) = paths_stack.last() {
|
||||
if let Some((prev_root_id, prev_path)) = prev_entry
|
||||
&& (root_id != prev_root_id || !directory_path.starts_with(prev_path))
|
||||
{
|
||||
paths_stack.pop();
|
||||
project_settings_stack.pop();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
let mut value = setting_value.from_default(&self.default_settings, cx);
|
||||
setting_value.refine(value.as_mut(), &refinements, cx);
|
||||
setting_value.refine(value.as_mut(), &project_settings_stack, cx);
|
||||
paths_stack.push(Some((*root_id, directory_path.as_ref())));
|
||||
let mut merged_local_settings = if let Some(deepest) = project_settings_stack.last() {
|
||||
(*deepest).clone()
|
||||
} else {
|
||||
self.merged_settings.as_ref().clone()
|
||||
};
|
||||
merged_local_settings.merge_from(Some(local_settings));
|
||||
|
||||
project_settings_stack.push(merged_local_settings);
|
||||
|
||||
// If a local settings file changed, then avoid recomputing local
|
||||
// settings for any path outside of that directory.
|
||||
if changed_local_path.is_some_and(|(changed_root_id, changed_local_path)| {
|
||||
*root_id != changed_root_id || !directory_path.starts_with(changed_local_path)
|
||||
}) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for setting_value in self.setting_values.values_mut() {
|
||||
let value =
|
||||
setting_value.from_settings(&project_settings_stack.last().unwrap(), cx);
|
||||
setting_value.set_local_value(*root_id, directory_path.clone(), value);
|
||||
}
|
||||
}
|
||||
@@ -1001,15 +1002,8 @@ impl Debug for SettingsStore {
|
||||
}
|
||||
|
||||
impl<T: Settings> AnySettingValue for SettingValue<T> {
|
||||
fn from_default(&self, s: &SettingsContent, cx: &mut App) -> Box<dyn Any> {
|
||||
Box::new(T::from_defaults(s, cx)) as _
|
||||
}
|
||||
|
||||
fn refine(&self, value: &mut dyn Any, refinements: &[&SettingsContent], cx: &mut App) {
|
||||
let value = value.downcast_mut::<T>().unwrap();
|
||||
for refinement in refinements {
|
||||
value.refine(refinement, cx)
|
||||
}
|
||||
fn from_settings(&self, s: &SettingsContent, cx: &mut App) -> Box<dyn Any> {
|
||||
Box::new(T::from_settings(s, cx)) as _
|
||||
}
|
||||
|
||||
fn setting_type_name(&self) -> &'static str {
|
||||
@@ -1072,7 +1066,6 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
use unindent::Unindent;
|
||||
use util::MergeFrom;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct AutoUpdateSetting {
|
||||
@@ -1080,19 +1073,11 @@ mod tests {
|
||||
}
|
||||
|
||||
impl Settings for AutoUpdateSetting {
|
||||
fn from_defaults(content: &SettingsContent, _: &mut App) -> Self {
|
||||
fn from_settings(content: &SettingsContent, _: &mut App) -> Self {
|
||||
AutoUpdateSetting {
|
||||
auto_update: content.auto_update.unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
fn refine(&mut self, content: &SettingsContent, _: &mut App) {
|
||||
if let Some(auto_update) = content.auto_update {
|
||||
self.auto_update = auto_update;
|
||||
}
|
||||
}
|
||||
|
||||
fn import_from_vscode(_: &VsCodeSettings, _: &mut SettingsContent) {}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -1102,7 +1087,7 @@ mod tests {
|
||||
}
|
||||
|
||||
impl Settings for TitleBarSettings {
|
||||
fn from_defaults(content: &SettingsContent, _: &mut App) -> Self {
|
||||
fn from_settings(content: &SettingsContent, _: &mut App) -> Self {
|
||||
let content = content.title_bar.clone().unwrap();
|
||||
TitleBarSettings {
|
||||
show: content.show.unwrap(),
|
||||
@@ -1110,13 +1095,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn refine(&mut self, content: &SettingsContent, _: &mut App) {
|
||||
let Some(content) = content.title_bar.as_ref() else {
|
||||
return;
|
||||
};
|
||||
self.show.merge_from(&content.show)
|
||||
}
|
||||
|
||||
fn import_from_vscode(vscode: &VsCodeSettings, content: &mut SettingsContent) {
|
||||
let mut show = None;
|
||||
|
||||
@@ -1138,7 +1116,7 @@ mod tests {
|
||||
}
|
||||
|
||||
impl Settings for DefaultLanguageSettings {
|
||||
fn from_defaults(content: &SettingsContent, _: &mut App) -> Self {
|
||||
fn from_settings(content: &SettingsContent, _: &mut App) -> Self {
|
||||
let content = &content.project.all_languages.defaults;
|
||||
DefaultLanguageSettings {
|
||||
tab_size: content.tab_size.unwrap(),
|
||||
@@ -1146,13 +1124,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn refine(&mut self, content: &SettingsContent, _: &mut App) {
|
||||
let content = &content.project.all_languages.defaults;
|
||||
self.tab_size.merge_from(&content.tab_size);
|
||||
self.preferred_line_length
|
||||
.merge_from(&content.preferred_line_length);
|
||||
}
|
||||
|
||||
fn import_from_vscode(vscode: &VsCodeSettings, content: &mut SettingsContent) {
|
||||
let content = &mut content.project.all_languages.defaults;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user