Move keymap editor into it's own crate and create settings ui crate

We also change the structure of the settings ui macro. The trait is
still a requirement on the Settings trait implementation, but it returns
a SettingUIItemVariant now, which the settings ui crate will take
adventage of to generate UI

This allows us to get around circular dependency errors and still get
the type system to ensure all settings fulfill the settings UI crate

Co-authored-by: Ben Kunkle <ben@zed.dev>
This commit is contained in:
Anthony 2025-08-26 12:00:10 -04:00
parent 3c0ec5f612
commit 15f634f8cc
53 changed files with 234 additions and 111 deletions

66
Cargo.lock generated
View file

@ -8953,6 +8953,46 @@ dependencies = [
"uuid", "uuid",
] ]
[[package]]
name = "keymap_editor"
version = "0.1.0"
dependencies = [
"anyhow",
"collections",
"command_palette",
"command_palette_hooks",
"component",
"db",
"editor",
"feature_flags",
"fs",
"fuzzy",
"gpui",
"itertools 0.14.0",
"language",
"log",
"menu",
"notifications",
"paths",
"project",
"search",
"serde",
"serde_json",
"settings",
"telemetry",
"tempfile",
"theme",
"tree-sitter-json",
"tree-sitter-rust",
"ui",
"ui_input",
"util",
"vim",
"workspace",
"workspace-hack",
"zed_actions",
]
[[package]] [[package]]
name = "khronos-egl" name = "khronos-egl"
version = "6.0.0" version = "6.0.0"
@ -14892,39 +14932,16 @@ name = "settings_ui"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collections",
"command_palette", "command_palette",
"command_palette_hooks", "command_palette_hooks",
"component",
"db",
"editor", "editor",
"feature_flags", "feature_flags",
"fs",
"fuzzy",
"gpui", "gpui",
"itertools 0.14.0",
"language",
"log",
"menu",
"notifications",
"paths",
"project",
"search",
"serde",
"serde_json",
"settings", "settings",
"telemetry",
"tempfile",
"theme", "theme",
"tree-sitter-json",
"tree-sitter-rust",
"ui", "ui",
"ui_input",
"util", "util",
"vim",
"workspace", "workspace",
"workspace-hack",
"zed_actions",
] ]
[[package]] [[package]]
@ -16749,6 +16766,7 @@ dependencies = [
"db", "db",
"gpui", "gpui",
"http_client", "http_client",
"keymap_editor",
"notifications", "notifications",
"pretty_assertions", "pretty_assertions",
"project", "project",
@ -16757,7 +16775,6 @@ dependencies = [
"schemars", "schemars",
"serde", "serde",
"settings", "settings",
"settings_ui",
"smallvec", "smallvec",
"story", "story",
"telemetry", "telemetry",
@ -20469,6 +20486,7 @@ dependencies = [
"itertools 0.14.0", "itertools 0.14.0",
"jj_ui", "jj_ui",
"journal", "journal",
"keymap_editor",
"language", "language",
"language_extension", "language_extension",
"language_model", "language_model",

View file

@ -54,6 +54,8 @@ members = [
"crates/deepseek", "crates/deepseek",
"crates/diagnostics", "crates/diagnostics",
"crates/docs_preprocessor", "crates/docs_preprocessor",
"crates/edit_prediction",
"crates/edit_prediction_button",
"crates/editor", "crates/editor",
"crates/eval", "crates/eval",
"crates/explorer_command_injector", "crates/explorer_command_injector",
@ -82,13 +84,12 @@ members = [
"crates/http_client_tls", "crates/http_client_tls",
"crates/icons", "crates/icons",
"crates/image_viewer", "crates/image_viewer",
"crates/edit_prediction",
"crates/edit_prediction_button",
"crates/inspector_ui", "crates/inspector_ui",
"crates/install_cli", "crates/install_cli",
"crates/jj", "crates/jj",
"crates/jj_ui", "crates/jj_ui",
"crates/journal", "crates/journal",
"crates/keymap_editor",
"crates/language", "crates/language",
"crates/language_extension", "crates/language_extension",
"crates/language_model", "crates/language_model",
@ -157,9 +158,9 @@ members = [
"crates/streaming_diff", "crates/streaming_diff",
"crates/sum_tree", "crates/sum_tree",
"crates/supermaven", "crates/supermaven",
"crates/system_specs",
"crates/supermaven_api", "crates/supermaven_api",
"crates/svg_preview", "crates/svg_preview",
"crates/system_specs",
"crates/tab_switcher", "crates/tab_switcher",
"crates/task", "crates/task",
"crates/tasks_ui", "crates/tasks_ui",
@ -315,6 +316,7 @@ install_cli = { path = "crates/install_cli" }
jj = { path = "crates/jj" } jj = { path = "crates/jj" }
jj_ui = { path = "crates/jj_ui" } jj_ui = { path = "crates/jj_ui" }
journal = { path = "crates/journal" } journal = { path = "crates/journal" }
keymap_editor = { path = "crates/keymap_editor" }
language = { path = "crates/language" } language = { path = "crates/language" }
language_extension = { path = "crates/language_extension" } language_extension = { path = "crates/language_extension" }
language_model = { path = "crates/language_model" } language_model = { path = "crates/language_model" }

View file

@ -4,7 +4,7 @@ use collections::HashMap;
use gpui::{App, SharedString}; use gpui::{App, SharedString};
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources}; use settings::{SettingsUI, Settings, SettingsSources};
pub fn init(cx: &mut App) { pub fn init(cx: &mut App) {
AllAgentServersSettings::register(cx); AllAgentServersSettings::register(cx);

View file

@ -8,7 +8,7 @@ use gpui::{App, Pixels, SharedString};
use language_model::LanguageModel; use language_model::LanguageModel;
use schemars::{JsonSchema, json_schema}; use schemars::{JsonSchema, json_schema};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources}; use settings::{SettingsUI, Settings, SettingsSources};
use std::borrow::Cow; use std::borrow::Cow;
pub use crate::agent_profile::*; pub use crate::agent_profile::*;

View file

@ -2,7 +2,7 @@ use anyhow::Result;
use gpui::App; use gpui::App;
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources}; use settings::{SettingsUI, Settings, SettingsSources};
/// Settings for slash commands. /// Settings for slash commands.
#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, SettingsUI)] #[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, SettingsUI)]

View file

@ -2,7 +2,7 @@ use anyhow::Result;
use gpui::App; use gpui::App;
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources}; use settings::{SettingsUI, Settings, SettingsSources};
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, SettingsUI)] #[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, SettingsUI)]
pub struct AudioSettings { pub struct AudioSettings {

View file

@ -10,7 +10,7 @@ use paths::remote_servers_dir;
use release_channel::{AppCommitSha, ReleaseChannel}; use release_channel::{AppCommitSha, ReleaseChannel};
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources, SettingsStore}; use settings::{SettingsUI, Settings, SettingsSources, SettingsStore};
use smol::{fs, io::AsyncReadExt}; use smol::{fs, io::AsyncReadExt};
use smol::{fs::File, process::Command}; use smol::{fs::File, process::Command};
use std::{ use std::{

View file

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

View file

@ -31,7 +31,7 @@ use release_channel::{AppVersion, ReleaseChannel};
use rpc::proto::{AnyTypedEnvelope, EnvelopedMessage, PeerId, RequestMessage}; use rpc::proto::{AnyTypedEnvelope, EnvelopedMessage, PeerId, RequestMessage};
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources}; use settings::{SettingsUI, Settings, SettingsSources};
use std::{ use std::{
any::TypeId, any::TypeId,
convert::TryFrom, convert::TryFrom,

View file

@ -1,7 +1,7 @@
use gpui::Pixels; use gpui::Pixels;
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources}; use settings::{SettingsUI, Settings, SettingsSources};
use workspace::dock::DockPosition; use workspace::dock::DockPosition;
#[derive(Deserialize, Debug, SettingsUI)] #[derive(Deserialize, Debug, SettingsUI)]

View file

@ -2,7 +2,7 @@ use dap_types::SteppingGranularity;
use gpui::{App, Global}; use gpui::{App, Global};
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources}; use settings::{SettingsUI, Settings, SettingsSources};
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]

View file

@ -6,7 +6,7 @@ use language::CursorShape;
use project::project_settings::DiagnosticSeverity; use project::project_settings::DiagnosticSeverity;
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources, VsCodeSettings}; use settings::{SettingsUI, Settings, SettingsSources, VsCodeSettings};
use util::serde::default_true; use util::serde::default_true;
/// Imports from the VSCode settings at /// Imports from the VSCode settings at

View file

@ -3,7 +3,7 @@ use collections::HashMap;
use gpui::App; use gpui::App;
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources}; use settings::{SettingsUI, Settings, SettingsSources};
use std::sync::Arc; use std::sync::Arc;
#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, SettingsUI)] #[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, SettingsUI)]

View file

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

View file

@ -5,7 +5,7 @@ use git::GitHostingProviderRegistry;
use gpui::App; use gpui::App;
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsStore}; use settings::{SettingsUI, Settings, SettingsStore};
use url::Url; use url::Url;
use util::ResultExt as _; use util::ResultExt as _;

View file

@ -2,7 +2,7 @@ use editor::ShowScrollbar;
use gpui::Pixels; use gpui::Pixels;
use schemars::JsonSchema; use schemars::JsonSchema;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources}; use settings::{SettingsUI, Settings, SettingsSources};
use workspace::dock::DockPosition; use workspace::dock::DockPosition;
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]

View file

@ -2,7 +2,7 @@ use editor::{Editor, EditorSettings, MultiBufferSnapshot};
use gpui::{App, Entity, FocusHandle, Focusable, Subscription, Task, WeakEntity}; use gpui::{App, Entity, FocusHandle, Focusable, Subscription, Task, WeakEntity};
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources}; use settings::{SettingsUI, Settings, SettingsSources};
use std::{fmt::Write, num::NonZeroU32, time::Duration}; use std::{fmt::Write, num::NonZeroU32, time::Duration};
use text::{Point, Selection}; use text::{Point, Selection};
use ui::{ use ui::{

View file

@ -1,7 +1,7 @@
use gpui::App; use gpui::App;
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources}; use settings::{SettingsUI, Settings, SettingsSources};
/// The settings for the image viewer. /// The settings for the image viewer.
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Default, SettingsUI)] #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Default, SettingsUI)]

View file

@ -5,7 +5,7 @@ use editor::{Editor, SelectionEffects};
use gpui::{App, AppContext as _, Context, Window, actions}; use gpui::{App, AppContext as _, Context, Window, actions};
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources}; use settings::{SettingsUI, Settings, SettingsSources};
use std::{ use std::{
fs::OpenOptions, fs::OpenOptions,
path::{Path, PathBuf}, path::{Path, PathBuf},

View file

@ -0,0 +1,55 @@
[package]
name = "keymap_editor"
version = "0.1.0"
edition.workspace = true
publish.workspace = true
license = "GPL-3.0-or-later"
[lints]
workspace = true
[lib]
path = "src/keymap_editor.rs"
[dependencies]
anyhow.workspace = true
collections.workspace = true
command_palette.workspace = true
command_palette_hooks.workspace = true
component.workspace = true
db.workspace = true
editor.workspace = true
feature_flags.workspace = true
fs.workspace = true
fuzzy.workspace = true
gpui.workspace = true
itertools.workspace = true
language.workspace = true
log.workspace = true
menu.workspace = true
notifications.workspace = true
paths.workspace = true
project.workspace = true
search.workspace = true
serde.workspace = true
serde_json.workspace = true
settings.workspace = true
telemetry.workspace = true
tempfile.workspace = true
theme.workspace = true
tree-sitter-json.workspace = true
tree-sitter-rust.workspace = true
ui.workspace = true
ui_input.workspace = true
util.workspace = true
vim.workspace = true
workspace-hack.workspace = true
workspace.workspace = true
zed_actions.workspace = true
[dev-dependencies]
db = {"workspace"= true, "features" = ["test-support"]}
fs = { workspace = true, features = ["test-support"] }
gpui = { workspace = true, features = ["test-support"] }
project = { workspace = true, features = ["test-support"] }
workspace = { workspace = true, features = ["test-support"] }

View file

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

View file

@ -1,3 +1,5 @@
mod ui_components;
use std::{ use std::{
cmp::{self}, cmp::{self},
ops::{Not as _, Range}, ops::{Not as _, Range},
@ -35,7 +37,7 @@ use workspace::{
}; };
use crate::{ use crate::{
keybindings::persistence::KEYBINDING_EDITORS, persistence::KEYBINDING_EDITORS,
ui_components::{ ui_components::{
keystroke_input::{ClearKeystrokes, KeystrokeInput, StartRecording, StopRecording}, keystroke_input::{ClearKeystrokes, KeystrokeInput, StartRecording, StopRecording},
table::{ColumnWidths, ResizeBehavior, Table, TableInteractionState}, table::{ColumnWidths, ResizeBehavior, Table, TableInteractionState},

View file

@ -17,8 +17,7 @@ use serde::{
}; };
use settings::{ use settings::{
DeriveSettingsUI as SettingsUI, ParameterizedJsonSchema, Settings, SettingsLocation, ParameterizedJsonSchema, Settings, SettingsLocation, SettingsSources, SettingsStore, SettingsUI,
SettingsSources, SettingsStore,
}; };
use shellexpand; use shellexpand;
use std::{borrow::Cow, num::NonZeroU32, path::Path, slice, sync::Arc}; use std::{borrow::Cow, num::NonZeroU32, path::Path, slice, sync::Arc};

View file

@ -5,7 +5,7 @@ use collections::HashMap;
use gpui::App; use gpui::App;
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources}; use settings::{SettingsUI, Settings, SettingsSources};
use crate::provider::{ use crate::provider::{
self, self,

View file

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

View file

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

View file

@ -18,7 +18,7 @@ use rpc::{
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{ use settings::{
DeriveSettingsUI as SettingsUI, InvalidSettingsError, LocalSettingsKind, Settings, SettingsUI, InvalidSettingsError, LocalSettingsKind, Settings,
SettingsLocation, SettingsSources, SettingsStore, parse_json_with_comments, watch_config_file, SettingsLocation, SettingsSources, SettingsStore, parse_json_with_comments, watch_config_file,
}; };
use std::{ use std::{

View file

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

View file

@ -19,7 +19,7 @@ use remote::ssh_session::{ConnectionIdentifier, SshPortForwardOption};
use remote::{SshConnectionOptions, SshPlatform, SshRemoteClient}; use remote::{SshConnectionOptions, SshPlatform, SshRemoteClient};
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources}; use settings::{SettingsUI, Settings, SettingsSources};
use theme::ThemeSettings; use theme::ThemeSettings;
use ui::{ use ui::{
ActiveTheme, Color, Context, Icon, IconName, IconSize, InteractiveElement, IntoElement, Label, ActiveTheme, Color, Context, Icon, IconName, IconSize, InteractiveElement, IntoElement, Label,

View file

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

View file

@ -5,6 +5,7 @@ mod keymap_file;
mod settings_file; mod settings_file;
mod settings_json; mod settings_json;
mod settings_store; mod settings_store;
mod settings_ui;
mod vscode_import; mod vscode_import;
use gpui::{App, Global}; use gpui::{App, Global};
@ -23,10 +24,11 @@ pub use settings_file::*;
pub use settings_json::*; pub use settings_json::*;
pub use settings_store::{ pub use settings_store::{
InvalidSettingsError, LocalSettingsKind, Settings, SettingsLocation, SettingsSources, InvalidSettingsError, LocalSettingsKind, Settings, SettingsLocation, SettingsSources,
SettingsStore, SettingsUI, SettingsStore,
}; };
pub use settings_ui::*;
// Re-export the derive macro // Re-export the derive macro
pub use settings_ui_macros::SettingsUI as DeriveSettingsUI; pub use settings_ui_macros::SettingsUI;
pub use vscode_import::{VsCodeSettings, VsCodeSettingsSource}; pub use vscode_import::{VsCodeSettings, VsCodeSettingsSource};
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]

View file

@ -32,11 +32,9 @@ pub type EditorconfigProperties = ec4rs::Properties;
use crate::{ use crate::{
ActiveSettingsProfileName, ParameterizedJsonSchema, SettingsJsonSchemaParams, VsCodeSettings, ActiveSettingsProfileName, ParameterizedJsonSchema, SettingsJsonSchemaParams, VsCodeSettings,
WorktreeId, parse_json_with_comments, update_value_in_json_text, WorktreeId, parse_json_with_comments, settings_ui::SettingsUI, update_value_in_json_text,
}; };
pub trait SettingsUI {}
/// A value that can be defined as a user setting. /// A value that can be defined as a user setting.
/// ///
/// Settings can be loaded from a combination of multiple JSON files. /// Settings can be loaded from a combination of multiple JSON files.

View file

@ -0,0 +1,72 @@
use std::any::Any;
use gpui::{AnyElement, App, Window};
pub trait SettingsUI {
fn ui_item() -> SettingsUIItem {
SettingsUIItem {
item: SettingsUIItemVariant::None,
}
}
}
pub struct SettingsUIItem {
// TODO:
// path: SmallVec<[&'static str; 8]>,
pub item: SettingsUIItemVariant,
}
pub enum SettingsUIItemVariant {
Group(SettingsUIItemGroup),
Item(SettingsUIItemSingle),
// TODO: remove
None,
}
pub struct SettingsUIItemGroup {
pub items: Vec<SettingsUIItem>,
}
pub enum SettingsUIItemSingle {
// TODO: default/builtin variants
Custom(Box<dyn Fn(&dyn Any, &mut Window, &mut App) -> AnyElement>),
}
/* NOTES:
# Root Group
some_setting: {
# First Item
# this shouldn't be a group
# it should just be item with path "some_bool.enabled" and title "Some Bool"
"some_bool": {
# this should
enabled: true | false
}
# Second Item
"some_other_thing": "foo" | "bar" | "baz"
}
Structure:
Group {
path: "some_item",
items: [
Item(
path: ["some_bool", "enabled"],
),
Item(
path: ["some_other_thing"],
)
]
}
is the following better than "foo.enabled"?
- for objects with single key "enabled", should just be a bool, with no "enabled"
for objects with enabled and other settings, enabled should be implicit,
so
"vim": false, # disabled
"vim": true, # enabled with default settings
"vim": {
"default_mode": "HelixNormal"
} # enabled with custom settings
*/

View file

@ -11,45 +11,24 @@ workspace = true
[lib] [lib]
path = "src/settings_ui.rs" path = "src/settings_ui.rs"
[features]
default = []
[dependencies] [dependencies]
anyhow.workspace = true anyhow.workspace = true
collections.workspace = true
command_palette.workspace = true command_palette.workspace = true
command_palette_hooks.workspace = true command_palette_hooks.workspace = true
component.workspace = true
db.workspace = true
editor.workspace = true editor.workspace = true
feature_flags.workspace = true feature_flags.workspace = true
fs.workspace = true
fuzzy.workspace = true
gpui.workspace = true gpui.workspace = true
itertools.workspace = true
language.workspace = true
log.workspace = true
menu.workspace = true
notifications.workspace = true
paths.workspace = true
project.workspace = true
search.workspace = true
serde.workspace = true
serde_json.workspace = true
settings.workspace = true
telemetry.workspace = true
tempfile.workspace = true
theme.workspace = true theme.workspace = true
tree-sitter-json.workspace = true settings.workspace = true
tree-sitter-rust.workspace = true
ui.workspace = true ui.workspace = true
ui_input.workspace = true
util.workspace = true util.workspace = true
vim.workspace = true
workspace-hack.workspace = true
workspace.workspace = true workspace.workspace = true
zed_actions.workspace = true
[dev-dependencies] # Uncomment other workspace dependencies as needed
db = {"workspace"= true, "features" = ["test-support"]} # assistant.workspace = true
fs = { workspace = true, features = ["test-support"] } # client.workspace = true
gpui = { workspace = true, features = ["test-support"] } # project.workspace = true
project = { workspace = true, features = ["test-support"] } # settings.workspace = true
workspace = { workspace = true, features = ["test-support"] }

View file

@ -12,9 +12,6 @@ use workspace::{Workspace, with_active_or_new_workspace};
use crate::appearance_settings_controls::AppearanceSettingsControls; use crate::appearance_settings_controls::AppearanceSettingsControls;
pub mod keybindings;
pub mod ui_components;
pub struct SettingsUiFeatureFlag; pub struct SettingsUiFeatureFlag;
impl FeatureFlag for SettingsUiFeatureFlag { impl FeatureFlag for SettingsUiFeatureFlag {
@ -76,7 +73,6 @@ pub fn init(cx: &mut App) {
}) })
.detach(); .detach();
keybindings::init(cx);
} }
pub struct SettingsPage { pub struct SettingsPage {

View file

@ -6,7 +6,7 @@ use gpui::{AbsoluteLength, App, FontFallbacks, FontFeatures, FontWeight, Pixels,
use schemars::JsonSchema; use schemars::JsonSchema;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, SettingsSources}; use settings::{SettingsSources, SettingsUI};
use std::path::PathBuf; use std::path::PathBuf;
use task::Shell; use task::Shell;
use theme::FontFamilyName; use theme::FontFamilyName;

View file

@ -13,9 +13,7 @@ use gpui::{
use refineable::Refineable; use refineable::Refineable;
use schemars::{JsonSchema, json_schema}; use schemars::{JsonSchema, json_schema};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{ use settings::{ParameterizedJsonSchema, Settings, SettingsSources, SettingsUI};
DeriveSettingsUI as SettingsUI, ParameterizedJsonSchema, Settings, SettingsSources,
};
use std::sync::Arc; use std::sync::Arc;
use util::ResultExt as _; use util::ResultExt as _;
use util::schemars::replace_subschema; use util::schemars::replace_subschema;

View file

@ -42,7 +42,7 @@ rpc.workspace = true
schemars.workspace = true schemars.workspace = true
serde.workspace = true serde.workspace = true
settings.workspace = true settings.workspace = true
settings_ui.workspace = true keymap_editor.workspace = true
smallvec.workspace = true smallvec.workspace = true
story = { workspace = true, optional = true } story = { workspace = true, optional = true }
telemetry.workspace = true telemetry.workspace = true

View file

@ -27,10 +27,10 @@ use gpui::{
IntoElement, MouseButton, ParentElement, Render, StatefulInteractiveElement, Styled, IntoElement, MouseButton, ParentElement, Render, StatefulInteractiveElement, Styled,
Subscription, WeakEntity, Window, actions, div, Subscription, WeakEntity, Window, actions, div,
}; };
use keymap_editor;
use onboarding_banner::OnboardingBanner; use onboarding_banner::OnboardingBanner;
use project::Project; use project::Project;
use settings::Settings as _; use settings::Settings as _;
use settings_ui::keybindings;
use std::sync::Arc; use std::sync::Arc;
use theme::ActiveTheme; use theme::ActiveTheme;
use title_bar_settings::TitleBarSettings; use title_bar_settings::TitleBarSettings;
@ -681,7 +681,7 @@ impl TitleBar {
"Settings Profiles", "Settings Profiles",
zed_actions::settings_profile_selector::Toggle.boxed_clone(), zed_actions::settings_profile_selector::Toggle.boxed_clone(),
) )
.action("Key Bindings", Box::new(keybindings::OpenKeymapEditor)) .action("Key Bindings", Box::new(keymap_editor::OpenKeymapEditor))
.action( .action(
"Themes…", "Themes…",
zed_actions::theme_selector::Toggle::default().boxed_clone(), zed_actions::theme_selector::Toggle::default().boxed_clone(),
@ -729,7 +729,7 @@ impl TitleBar {
"Settings Profiles", "Settings Profiles",
zed_actions::settings_profile_selector::Toggle.boxed_clone(), zed_actions::settings_profile_selector::Toggle.boxed_clone(),
) )
.action("Key Bindings", Box::new(keybindings::OpenKeymapEditor)) .action("Key Bindings", Box::new(keymap_editor::OpenKeymapEditor))
.action( .action(
"Themes…", "Themes…",
zed_actions::theme_selector::Toggle::default().boxed_clone(), zed_actions::theme_selector::Toggle::default().boxed_clone(),

View file

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

View file

@ -40,7 +40,7 @@ use schemars::JsonSchema;
use serde::Deserialize; use serde::Deserialize;
use serde_derive::Serialize; use serde_derive::Serialize;
use settings::{ use settings::{
DeriveSettingsUI as SettingsUI, Settings, SettingsSources, SettingsStore, update_settings_file, SettingsUI, Settings, SettingsSources, SettingsStore, update_settings_file,
}; };
use state::{Mode, Operator, RecordedSelection, SearchState, VimGlobals}; use state::{Mode, Operator, RecordedSelection, SearchState, VimGlobals};
use std::{mem, ops::Range, sync::Arc}; use std::{mem, ops::Range, sync::Arc};

View file

@ -6,7 +6,7 @@
use anyhow::Result; use anyhow::Result;
use gpui::App; use gpui::App;
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources}; use settings::{Settings, SettingsSources, SettingsUI};
/// Initializes the `vim_mode_setting` crate. /// Initializes the `vim_mode_setting` crate.
pub fn init(cx: &mut App) { pub fn init(cx: &mut App) {

View file

@ -17,7 +17,7 @@ use gpui::{
use project::{Project, ProjectEntryId, ProjectPath}; use project::{Project, ProjectEntryId, ProjectPath};
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsLocation, SettingsSources}; use settings::{SettingsUI, Settings, SettingsLocation, SettingsSources};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{ use std::{
any::{Any, TypeId}, any::{Any, TypeId},

View file

@ -6,7 +6,7 @@ use collections::HashMap;
use gpui::App; use gpui::App;
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsSources}; use settings::{SettingsUI, Settings, SettingsSources};
#[derive(Deserialize, SettingsUI)] #[derive(Deserialize, SettingsUI)]
pub struct WorkspaceSettings { pub struct WorkspaceSettings {

View file

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

View file

@ -131,6 +131,7 @@ serde_json.workspace = true
session.workspace = true session.workspace = true
settings.workspace = true settings.workspace = true
settings_ui.workspace = true settings_ui.workspace = true
keymap_editor.workspace = true
shellexpand.workspace = true shellexpand.workspace = true
smol.workspace = true smol.workspace = true
snippet_provider.workspace = true snippet_provider.workspace = true

View file

@ -632,6 +632,7 @@ pub fn main() {
svg_preview::init(cx); svg_preview::init(cx);
onboarding::init(cx); onboarding::init(cx);
settings_ui::init(cx); settings_ui::init(cx);
keymap_editor::init(cx);
extensions_ui::init(cx); extensions_ui::init(cx);
zeta::init(cx); zeta::init(cx);
inspector_ui::init(app_state.clone(), cx); inspector_ui::init(app_state.clone(), cx);

View file

@ -1482,7 +1482,7 @@ fn reload_keymaps(cx: &mut App, mut user_key_bindings: Vec<KeyBinding>) {
workspace::NewWindow, workspace::NewWindow,
)]); )]);
// todo: nicer api here? // todo: nicer api here?
settings_ui::keybindings::KeymapEventChannel::trigger_keymap_changed(cx); keymap_editor::KeymapEventChannel::trigger_keymap_changed(cx);
} }
pub fn load_default_keymap(cx: &mut App) { pub fn load_default_keymap(cx: &mut App) {

View file

@ -1,6 +1,5 @@
use collab_ui::collab_panel; use collab_ui::collab_panel;
use gpui::{Menu, MenuItem, OsAction}; use gpui::{Menu, MenuItem, OsAction};
use settings_ui::keybindings;
use terminal_view::terminal_panel; use terminal_view::terminal_panel;
pub fn app_menus() -> Vec<Menu> { pub fn app_menus() -> Vec<Menu> {
@ -17,7 +16,7 @@ pub fn app_menus() -> Vec<Menu> {
name: "Settings".into(), name: "Settings".into(),
items: vec![ items: vec![
MenuItem::action("Open Settings", super::OpenSettings), MenuItem::action("Open Settings", super::OpenSettings),
MenuItem::action("Open Key Bindings", keybindings::OpenKeymapEditor), MenuItem::action("Open Key Bindings", keymap_editor::OpenKeymapEditor),
MenuItem::action("Open Default Settings", super::OpenDefaultSettings), MenuItem::action("Open Default Settings", super::OpenDefaultSettings),
MenuItem::action( MenuItem::action(
"Open Default Key Bindings", "Open Default Key Bindings",

View file

@ -3,7 +3,7 @@ use anyhow::Result;
use gpui::App; use gpui::App;
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{DeriveSettingsUI as SettingsUI, Settings, SettingsStore}; use settings::{SettingsUI, Settings, SettingsStore};
pub fn init(cx: &mut App) { pub fn init(cx: &mut App) {
ZlogSettings::register(cx); ZlogSettings::register(cx);