Start work on creating the inital structure for the settings UI

We created a proc macro that derives the settings ui trait on types and
added that trait as a marker on Settings trait. Then we added the derive
macro on all settings

Co-authored-by: Ben Kunkle <ben@zed.dev>
This commit is contained in:
Anthony 2025-08-25 15:42:15 -04:00
parent 5fd29d37a6
commit 3c0ec5f612
43 changed files with 170 additions and 82 deletions

10
Cargo.lock generated
View file

@ -14856,6 +14856,7 @@ dependencies = [
"serde_derive",
"serde_json",
"serde_json_lenient",
"settings_ui_macros",
"smallvec",
"tree-sitter",
"tree-sitter-json",
@ -14926,6 +14927,15 @@ dependencies = [
"zed_actions",
]
[[package]]
name = "settings_ui_macros"
version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
]
[[package]]
name = "sha1"
version = "0.10.6"

View file

@ -146,6 +146,7 @@ members = [
"crates/settings",
"crates/settings_profile_selector",
"crates/settings_ui",
"crates/settings_ui_macros",
"crates/snippet",
"crates/snippet_provider",
"crates/snippets_ui",
@ -373,6 +374,7 @@ semantic_version = { path = "crates/semantic_version" }
session = { path = "crates/session" }
settings = { path = "crates/settings" }
settings_ui = { path = "crates/settings_ui" }
settings_ui_macros = { path = "crates/settings_ui_macros" }
snippet = { path = "crates/snippet" }
snippet_provider = { path = "crates/snippet_provider" }
snippets_ui = { path = "crates/snippets_ui" }

View file

@ -4,13 +4,13 @@ use collections::HashMap;
use gpui::{App, SharedString};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
pub fn init(cx: &mut App) {
AllAgentServersSettings::register(cx);
}
#[derive(Default, Deserialize, Serialize, Clone, JsonSchema, Debug)]
#[derive(Default, Deserialize, Serialize, Clone, JsonSchema, Debug, SettingsUI)]
pub struct AllAgentServersSettings {
pub gemini: Option<AgentServerSettings>,
pub claude: Option<AgentServerSettings>,

View file

@ -8,7 +8,7 @@ use gpui::{App, Pixels, SharedString};
use language_model::LanguageModel;
use schemars::{JsonSchema, json_schema};
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
use std::borrow::Cow;
pub use crate::agent_profile::*;
@ -48,7 +48,7 @@ pub enum NotifyWhenAgentWaiting {
Never,
}
#[derive(Default, Clone, Debug)]
#[derive(Default, Clone, Debug, SettingsUI)]
pub struct AgentSettings {
pub enabled: bool,
pub button: bool,

View file

@ -2,10 +2,10 @@ use anyhow::Result;
use gpui::App;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
/// Settings for slash commands.
#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema)]
#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, SettingsUI)]
pub struct SlashCommandSettings {
/// Settings for the `/cargo-workspace` slash command.
#[serde(default)]

View file

@ -2,9 +2,9 @@ use anyhow::Result;
use gpui::App;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
#[derive(Deserialize, Debug)]
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, SettingsUI)]
pub struct AudioSettings {
/// Opt into the new audio system.
#[serde(rename = "experimental.rodio_audio", default)]

View file

@ -10,7 +10,7 @@ use paths::remote_servers_dir;
use release_channel::{AppCommitSha, ReleaseChannel};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources, SettingsStore};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources, SettingsStore};
use smol::{fs, io::AsyncReadExt};
use smol::{fs::File, process::Command};
use std::{
@ -113,6 +113,7 @@ impl Drop for MacOsUnmounter {
}
}
#[derive(SettingsUI)]
struct AutoUpdateSetting(bool);
/// Whether or not to automatically check for updates.

View file

@ -2,9 +2,9 @@ use anyhow::Result;
use gpui::App;
use schemars::JsonSchema;
use serde_derive::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
#[derive(Deserialize, Debug)]
#[derive(Deserialize, Debug, SettingsUI)]
pub struct CallSettings {
pub mute_on_join: bool,
pub share_on_join: bool,

View file

@ -31,7 +31,7 @@ use release_channel::{AppVersion, ReleaseChannel};
use rpc::proto::{AnyTypedEnvelope, EnvelopedMessage, PeerId, RequestMessage};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
use std::{
any::TypeId,
convert::TryFrom,
@ -101,7 +101,7 @@ pub struct ClientSettingsContent {
server_url: Option<String>,
}
#[derive(Deserialize)]
#[derive(Deserialize, SettingsUI)]
pub struct ClientSettings {
pub server_url: String,
}
@ -127,7 +127,7 @@ pub struct ProxySettingsContent {
proxy: Option<String>,
}
#[derive(Deserialize, Default)]
#[derive(Deserialize, Default, SettingsUI)]
pub struct ProxySettings {
pub proxy: Option<String>,
}
@ -504,7 +504,7 @@ impl<T: 'static> Drop for PendingEntitySubscription<T> {
}
}
#[derive(Copy, Clone, Deserialize, Debug)]
#[derive(Copy, Clone, Deserialize, Debug, SettingsUI)]
pub struct TelemetrySettings {
pub diagnostics: bool,
pub metrics: bool,

View file

@ -1,10 +1,10 @@
use gpui::Pixels;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
use workspace::dock::DockPosition;
#[derive(Deserialize, Debug)]
#[derive(Deserialize, Debug, SettingsUI)]
pub struct CollaborationPanelSettings {
pub button: bool,
pub dock: DockPosition,
@ -20,7 +20,7 @@ pub enum ChatPanelButton {
WhenInCall,
}
#[derive(Deserialize, Debug)]
#[derive(Deserialize, Debug, SettingsUI)]
pub struct ChatPanelSettings {
pub button: ChatPanelButton,
pub dock: DockPosition,
@ -43,7 +43,7 @@ pub struct ChatPanelSettingsContent {
pub default_width: Option<f32>,
}
#[derive(Deserialize, Debug)]
#[derive(Deserialize, Debug, SettingsUI)]
pub struct NotificationPanelSettings {
pub button: bool,
pub dock: DockPosition,
@ -66,7 +66,7 @@ pub struct PanelSettingsContent {
pub default_width: Option<f32>,
}
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)]
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, SettingsUI)]
pub struct MessageEditorSettings {
/// Whether to automatically replace emoji shortcodes with emoji characters.
/// For example: typing `:wave:` gets replaced with `👋`.

View file

@ -2,7 +2,7 @@ use dap_types::SteppingGranularity;
use gpui::{App, Global};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
@ -12,7 +12,7 @@ pub enum DebugPanelDockPosition {
Right,
}
#[derive(Serialize, Deserialize, JsonSchema, Clone, Copy)]
#[derive(Serialize, Deserialize, JsonSchema, Clone, Copy, SettingsUI)]
#[serde(default)]
pub struct DebuggerSettings {
/// Determines the stepping granularity.

View file

@ -6,12 +6,12 @@ use language::CursorShape;
use project::project_settings::DiagnosticSeverity;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources, VsCodeSettings};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources, VsCodeSettings};
use util::serde::default_true;
/// Imports from the VSCode settings at
/// https://code.visualstudio.com/docs/reference/default-settings
#[derive(Deserialize, Clone)]
#[derive(Deserialize, Clone, SettingsUI)]
pub struct EditorSettings {
pub cursor_blink: bool,
pub cursor_shape: Option<CursorShape>,

View file

@ -3,10 +3,10 @@ use collections::HashMap;
use gpui::App;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
use std::sync::Arc;
#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema)]
#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, SettingsUI)]
pub struct ExtensionSettings {
/// The extensions that should be automatically installed by Zed.
///

View file

@ -1,9 +1,9 @@
use anyhow::Result;
use schemars::JsonSchema;
use serde_derive::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
#[derive(Deserialize, Debug, Clone, Copy, PartialEq, SettingsUI)]
pub struct FileFinderSettings {
pub file_icons: bool,
pub modal_max_width: Option<FileFinderWidth>,

View file

@ -5,7 +5,7 @@ use git::GitHostingProviderRegistry;
use gpui::App;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsStore};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsStore};
use url::Url;
use util::ResultExt as _;
@ -78,7 +78,7 @@ pub struct GitHostingProviderConfig {
pub name: String,
}
#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, SettingsUI)]
pub struct GitHostingProviderSettings {
/// The list of custom Git hosting providers.
#[serde(default)]

View file

@ -2,7 +2,7 @@ use editor::ShowScrollbar;
use gpui::Pixels;
use schemars::JsonSchema;
use serde_derive::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
use workspace::dock::DockPosition;
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
@ -77,7 +77,7 @@ pub struct GitPanelSettingsContent {
pub collapse_untracked_diff: Option<bool>,
}
#[derive(Deserialize, Debug, Clone, PartialEq)]
#[derive(Deserialize, Debug, Clone, PartialEq, SettingsUI)]
pub struct GitPanelSettings {
pub button: bool,
pub dock: DockPosition,

View file

@ -2,7 +2,7 @@ use editor::{Editor, EditorSettings, MultiBufferSnapshot};
use gpui::{App, Entity, FocusHandle, Focusable, Subscription, Task, WeakEntity};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
use std::{fmt::Write, num::NonZeroU32, time::Duration};
use text::{Point, Selection};
use ui::{
@ -293,7 +293,7 @@ impl StatusItemView for CursorPosition {
}
}
#[derive(Clone, Copy, Default, PartialEq, JsonSchema, Deserialize, Serialize)]
#[derive(Clone, Copy, Default, PartialEq, JsonSchema, Deserialize, Serialize, SettingsUI)]
#[serde(rename_all = "snake_case")]
pub(crate) enum LineIndicatorFormat {
Short,

View file

@ -1,10 +1,10 @@
use gpui::App;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
/// The settings for the image viewer.
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Default)]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Default, SettingsUI)]
pub struct ImageViewerSettings {
/// The unit to use for displaying image file sizes.
///

View file

@ -5,7 +5,7 @@ use editor::{Editor, SelectionEffects};
use gpui::{App, AppContext as _, Context, Window, actions};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
use std::{
fs::OpenOptions,
path::{Path, PathBuf},
@ -22,7 +22,7 @@ actions!(
);
/// Settings specific to journaling
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, SettingsUI)]
pub struct JournalSettings {
/// The path of the directory where journal entries are stored.
///

View file

@ -17,7 +17,8 @@ use serde::{
};
use settings::{
ParameterizedJsonSchema, Settings, SettingsLocation, SettingsSources, SettingsStore,
DeriveSettingsUI as SettingsUI, ParameterizedJsonSchema, Settings, SettingsLocation,
SettingsSources, SettingsStore,
};
use shellexpand;
use std::{borrow::Cow, num::NonZeroU32, path::Path, slice, sync::Arc};
@ -55,7 +56,7 @@ pub fn all_language_settings<'a>(
}
/// The settings for all languages.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, SettingsUI)]
pub struct AllLanguageSettings {
/// The edit prediction settings.
pub edit_predictions: EditPredictionSettings,

View file

@ -5,7 +5,7 @@ use collections::HashMap;
use gpui::App;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
use crate::provider::{
self,
@ -29,7 +29,7 @@ pub fn init_settings(cx: &mut App) {
AllLanguageModelSettings::register(cx);
}
#[derive(Default)]
#[derive(Default, SettingsUI)]
pub struct AllLanguageModelSettings {
pub anthropic: AnthropicSettings,
pub bedrock: AmazonBedrockSettings,

View file

@ -2,7 +2,7 @@ use editor::ShowScrollbar;
use gpui::Pixels;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Copy, PartialEq)]
#[serde(rename_all = "snake_case")]
@ -18,7 +18,7 @@ pub enum ShowIndentGuides {
Never,
}
#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
#[derive(Deserialize, Debug, Clone, Copy, PartialEq, SettingsUI)]
pub struct OutlinePanelSettings {
pub button: bool,
pub default_width: Pixels,

View file

@ -948,7 +948,7 @@ pub enum PulledDiagnostics {
/// Whether to disable all AI features in Zed.
///
/// Default: false
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, settings::DeriveSettingsUI)]
pub struct DisableAiSettings {
pub disable_ai: bool,
}

View file

@ -18,8 +18,8 @@ use rpc::{
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{
InvalidSettingsError, LocalSettingsKind, Settings, SettingsLocation, SettingsSources,
SettingsStore, parse_json_with_comments, watch_config_file,
DeriveSettingsUI as SettingsUI, InvalidSettingsError, LocalSettingsKind, Settings,
SettingsLocation, SettingsSources, SettingsStore, parse_json_with_comments, watch_config_file,
};
use std::{
collections::BTreeMap,
@ -36,7 +36,7 @@ use crate::{
worktree_store::{WorktreeStore, WorktreeStoreEvent},
};
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, SettingsUI)]
pub struct ProjectSettings {
/// Configuration for language servers.
///

View file

@ -2,7 +2,7 @@ use editor::ShowScrollbar;
use gpui::Pixels;
use schemars::JsonSchema;
use serde_derive::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Copy, PartialEq)]
#[serde(rename_all = "snake_case")]
@ -28,7 +28,7 @@ pub enum EntrySpacing {
Standard,
}
#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
#[derive(Deserialize, Debug, Clone, Copy, PartialEq, SettingsUI)]
pub struct ProjectPanelSettings {
pub button: bool,
pub hide_gitignore: bool,

View file

@ -19,7 +19,7 @@ use remote::ssh_session::{ConnectionIdentifier, SshPortForwardOption};
use remote::{SshConnectionOptions, SshPlatform, SshRemoteClient};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
use theme::ThemeSettings;
use ui::{
ActiveTheme, Color, Context, Icon, IconName, IconSize, InteractiveElement, IntoElement, Label,
@ -28,7 +28,7 @@ use ui::{
use util::serde::default_true;
use workspace::{AppState, ModalView, Workspace};
#[derive(Deserialize)]
#[derive(Deserialize, SettingsUI)]
pub struct SshSettings {
pub ssh_connections: Option<Vec<SshConnection>>,
/// Whether to read ~/.ssh/config for ssh connection sources.

View file

@ -4,9 +4,9 @@ use editor::EditorSettings;
use gpui::App;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
#[derive(Debug, Default)]
#[derive(Debug, Default, SettingsUI)]
pub struct JupyterSettings {
pub kernel_selections: HashMap<String, String>,
}

View file

@ -31,6 +31,7 @@ schemars.workspace = true
serde.workspace = true
serde_derive.workspace = true
serde_json.workspace = true
settings_ui_macros.workspace = true
serde_json_lenient.workspace = true
smallvec.workspace = true
tree-sitter-json.workspace = true

View file

@ -1,6 +1,6 @@
use std::fmt::{Display, Formatter};
use crate::{Settings, SettingsSources, VsCodeSettings};
use crate::{Settings, SettingsSources, SettingsUI, VsCodeSettings};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
@ -96,6 +96,8 @@ impl BaseKeymap {
}
}
impl SettingsUI for BaseKeymap {}
impl Settings for BaseKeymap {
const KEY: Option<&'static str> = Some("base_keymap");

View file

@ -23,8 +23,10 @@ pub use settings_file::*;
pub use settings_json::*;
pub use settings_store::{
InvalidSettingsError, LocalSettingsKind, Settings, SettingsLocation, SettingsSources,
SettingsStore,
SettingsStore, SettingsUI,
};
// Re-export the derive macro
pub use settings_ui_macros::SettingsUI as DeriveSettingsUI;
pub use vscode_import::{VsCodeSettings, VsCodeSettingsSource};
#[derive(Clone, Debug, PartialEq)]

View file

@ -35,10 +35,12 @@ use crate::{
WorktreeId, parse_json_with_comments, update_value_in_json_text,
};
pub trait SettingsUI {}
/// A value that can be defined as a user setting.
///
/// Settings can be loaded from a combination of multiple JSON files.
pub trait Settings: 'static + Send + Sync {
pub trait Settings: SettingsUI + 'static + Send + Sync {
/// The name of a key within the JSON file from which this setting should
/// be deserialized. If this is `None`, then the setting will be deserialized
/// from the root object.
@ -1505,7 +1507,10 @@ mod tests {
use crate::VsCodeSettingsSource;
use super::*;
// This is so the SettingsUI macro can still work properly
use crate as settings;
use serde_derive::Deserialize;
use settings_ui_macros::SettingsUI;
use unindent::Unindent;
#[gpui::test]
@ -2048,14 +2053,14 @@ mod tests {
pretty_assertions::assert_eq!(new, expected);
}
#[derive(Debug, PartialEq, Deserialize)]
#[derive(Debug, PartialEq, Deserialize, SettingsUI)]
struct UserSettings {
name: String,
age: u32,
staff: bool,
}
#[derive(Default, Clone, Serialize, Deserialize, JsonSchema)]
#[derive(Default, Clone, Serialize, Deserialize, JsonSchema, SettingsUI)]
struct UserSettingsContent {
name: Option<String>,
age: Option<u32>,
@ -2075,7 +2080,7 @@ mod tests {
}
}
#[derive(Debug, Deserialize, PartialEq)]
#[derive(Debug, Deserialize, PartialEq, SettingsUI)]
struct TurboSetting(bool);
impl Settings for TurboSetting {
@ -2089,7 +2094,7 @@ mod tests {
fn import_from_vscode(_vscode: &VsCodeSettings, _current: &mut Self::FileContent) {}
}
#[derive(Clone, Debug, PartialEq, Deserialize)]
#[derive(Clone, Debug, PartialEq, Deserialize, SettingsUI)]
struct MultiKeySettings {
#[serde(default)]
key1: String,
@ -2122,7 +2127,7 @@ mod tests {
}
}
#[derive(Debug, Deserialize)]
#[derive(Debug, Deserialize, SettingsUI)]
struct JournalSettings {
pub path: String,
pub hour_format: HourFormat,
@ -2223,7 +2228,7 @@ mod tests {
);
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, SettingsUI)]
struct LanguageSettings {
#[serde(default)]
languages: HashMap<String, LanguageSettingEntry>,

View file

@ -0,0 +1,21 @@
[package]
name = "settings_ui_macros"
version = "0.1.0"
edition.workspace = true
publish.workspace = true
license = "GPL-3.0-or-later"
[lib]
path = "src/settings_ui_macros.rs"
proc-macro = true
[lints]
workspace = true
[features]
default = []
[dependencies]
proc-macro2.workspace = true
quote.workspace = true
syn.workspace = true

View file

@ -0,0 +1 @@
../../LICENSE-GPL

View file

@ -0,0 +1,36 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{DeriveInput, parse_macro_input};
/// Derive macro for the `SettingsUI` marker trait.
///
/// This macro automatically implements the `SettingsUI` trait for the annotated type.
/// The `SettingsUI` trait is a marker trait used to indicate that a type can be
/// displayed in the settings UI.
///
/// # Example
///
/// ```
/// use settings::SettingsUI;
/// use settings_ui_macros::SettingsUI;
///
/// #[derive(SettingsUI)]
/// struct MySettings {
/// enabled: bool,
/// count: usize,
/// }
/// ```
#[proc_macro_derive(SettingsUI)]
pub fn derive_settings_ui(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let name = &input.ident;
// Handle generic parameters if present
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let expanded = quote! {
impl #impl_generics settings::SettingsUI for #name #ty_generics #where_clause {}
};
TokenStream::from(expanded)
}

View file

@ -6,7 +6,7 @@ use gpui::{AbsoluteLength, App, FontFallbacks, FontFeatures, FontWeight, Pixels,
use schemars::JsonSchema;
use serde_derive::{Deserialize, Serialize};
use settings::SettingsSources;
use settings::{DeriveSettingsUI as SettingsUI, SettingsSources};
use std::path::PathBuf;
use task::Shell;
use theme::FontFamilyName;
@ -24,7 +24,7 @@ pub struct Toolbar {
pub breadcrumbs: bool,
}
#[derive(Clone, Debug, Deserialize)]
#[derive(Clone, Debug, Deserialize, SettingsUI)]
pub struct TerminalSettings {
pub shell: Shell,
pub working_directory: WorkingDirectory,

View file

@ -13,7 +13,9 @@ use gpui::{
use refineable::Refineable;
use schemars::{JsonSchema, json_schema};
use serde::{Deserialize, Serialize};
use settings::{ParameterizedJsonSchema, Settings, SettingsSources};
use settings::{
DeriveSettingsUI as SettingsUI, ParameterizedJsonSchema, Settings, SettingsSources,
};
use std::sync::Arc;
use util::ResultExt as _;
use util::schemars::replace_subschema;
@ -87,7 +89,7 @@ impl From<UiDensity> for String {
}
/// Customizable settings for the UI and theme system.
#[derive(Clone, PartialEq)]
#[derive(Clone, PartialEq, SettingsUI)]
pub struct ThemeSettings {
/// The UI font size. Determines the size of text in the UI,
/// as well as the size of a [gpui::Rems] unit.

View file

@ -1,9 +1,9 @@
use db::anyhow;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
#[derive(Copy, Clone, Deserialize, Debug)]
#[derive(Copy, Clone, Deserialize, Debug, SettingsUI)]
pub struct TitleBarSettings {
pub show_branch_icon: bool,
pub show_onboarding_banner: bool,

View file

@ -39,7 +39,9 @@ use object::Object;
use schemars::JsonSchema;
use serde::Deserialize;
use serde_derive::Serialize;
use settings::{Settings, SettingsSources, SettingsStore, update_settings_file};
use settings::{
DeriveSettingsUI as SettingsUI, Settings, SettingsSources, SettingsStore, update_settings_file,
};
use state::{Mode, Operator, RecordedSelection, SearchState, VimGlobals};
use std::{mem, ops::Range, sync::Arc};
use surrounds::SurroundsType;
@ -1774,7 +1776,7 @@ struct CursorShapeSettings {
pub insert: Option<CursorShape>,
}
#[derive(Deserialize)]
#[derive(Deserialize, SettingsUI)]
struct VimSettings {
pub default_mode: Mode,
pub toggle_relative_line_numbers: bool,

View file

@ -6,7 +6,7 @@
use anyhow::Result;
use gpui::App;
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
/// Initializes the `vim_mode_setting` crate.
pub fn init(cx: &mut App) {
@ -17,6 +17,7 @@ pub fn init(cx: &mut App) {
/// Whether or not to enable Vim mode.
///
/// Default: false
#[derive(SettingsUI)]
pub struct VimModeSetting(pub bool);
impl Settings for VimModeSetting {
@ -43,6 +44,7 @@ impl Settings for VimModeSetting {
/// Whether or not to enable Helix mode.
///
/// Default: false
#[derive(SettingsUI)]
pub struct HelixModeSetting(pub bool);
impl Settings for HelixModeSetting {

View file

@ -17,7 +17,7 @@ use gpui::{
use project::{Project, ProjectEntryId, ProjectPath};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsLocation, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsLocation, SettingsSources};
use smallvec::SmallVec;
use std::{
any::{Any, TypeId},
@ -49,7 +49,7 @@ impl Default for SaveOptions {
}
}
#[derive(Deserialize)]
#[derive(Deserialize, SettingsUI)]
pub struct ItemSettings {
pub git_status: bool,
pub close_position: ClosePosition,
@ -59,7 +59,7 @@ pub struct ItemSettings {
pub show_close_button: ShowCloseButton,
}
#[derive(Deserialize)]
#[derive(Deserialize, SettingsUI)]
pub struct PreviewTabsSettings {
pub enabled: bool,
pub enable_preview_from_file_finder: bool,

View file

@ -6,9 +6,9 @@ use collections::HashMap;
use gpui::App;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
#[derive(Deserialize)]
#[derive(Deserialize, SettingsUI)]
pub struct WorkspaceSettings {
pub active_pane_modifiers: ActivePanelModifiers,
pub bottom_dock_layout: BottomDockLayout,
@ -204,7 +204,7 @@ pub struct WorkspaceSettingsContent {
pub close_on_file_delete: Option<bool>,
}
#[derive(Deserialize)]
#[derive(Deserialize, SettingsUI)]
pub struct TabBarSettings {
pub show: bool,
pub show_nav_history_buttons: bool,

View file

@ -4,10 +4,10 @@ use anyhow::Context as _;
use gpui::App;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources};
use util::paths::PathMatcher;
#[derive(Clone, PartialEq, Eq)]
#[derive(Clone, PartialEq, Eq, SettingsUI)]
pub struct WorktreeSettings {
pub file_scan_inclusions: PathMatcher,
pub file_scan_exclusions: PathMatcher,

View file

@ -3,7 +3,7 @@ use anyhow::Result;
use gpui::App;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsStore};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsStore};
pub fn init(cx: &mut App) {
ZlogSettings::register(cx);
@ -15,7 +15,7 @@ pub fn init(cx: &mut App) {
.detach();
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, SettingsUI)]
pub struct ZlogSettings {
#[serde(default, flatten)]
pub scopes: std::collections::HashMap<String, String>,