Add initial scaffolding for settings auto-registration

Mikayla Maki created

Change summary

crates/acp_thread/src/acp_thread.rs                               |  2 
crates/action_log/src/action_log.rs                               |  2 
crates/agent/src/agent_profile.rs                                 |  2 
crates/agent/src/context.rs                                       |  2 
crates/agent/src/thread.rs                                        |  2 
crates/agent2/src/agent.rs                                        |  2 
crates/agent2/src/db.rs                                           |  2 
crates/agent2/src/tools/edit_file_tool.rs                         |  2 
crates/agent2/src/tools/find_path_tool.rs                         |  2 
crates/agent2/src/tools/grep_tool.rs                              |  2 
crates/agent2/src/tools/list_directory_tool.rs                    |  2 
crates/agent2/src/tools/open_tool.rs                              |  2 
crates/agent2/src/tools/read_file_tool.rs                         |  2 
crates/agent_servers/src/e2e_tests.rs                             |  2 
crates/agent_ui/src/acp/entry_view_state.rs                       |  2 
crates/agent_ui/src/acp/thread_view.rs                            |  2 
crates/agent_ui/src/agent_configuration/add_llm_provider_modal.rs |  2 
crates/agent_ui/src/agent_diff.rs                                 |  4 
crates/agent_ui/src/buffer_codegen.rs                             |  2 
crates/agent_ui/src/context_picker/completion_provider.rs         |  2 
crates/agent_ui/src/text_thread_editor.rs                         |  2 
crates/assistant_context/src/assistant_context_tests.rs           |  1 
crates/assistant_slash_commands/src/file_command.rs               |  1 
crates/assistant_tools/src/edit_file_tool.rs                      |  4 
crates/assistant_tools/src/find_path_tool.rs                      |  2 
crates/assistant_tools/src/grep_tool.rs                           |  2 
crates/assistant_tools/src/list_directory_tool.rs                 |  2 
crates/assistant_tools/src/open_tool.rs                           |  2 
crates/assistant_tools/src/project_notifications_tool.rs          |  2 
crates/assistant_tools/src/read_file_tool.rs                      |  2 
crates/assistant_tools/src/terminal_tool.rs                       |  2 
crates/channel/src/channel_store_tests.rs                         |  2 
crates/client/src/client.rs                                       |  2 
crates/client/src/telemetry.rs                                    |  1 
crates/collab/src/tests/test_server.rs                            |  2 
crates/copilot/src/copilot_completion_provider.rs                 |  2 
crates/dap/src/client.rs                                          |  2 
crates/debugger_ui/src/tests.rs                                   |  2 
crates/diagnostics/src/diagnostics_tests.rs                       |  2 
crates/edit_prediction_context/src/edit_prediction_context.rs     |  2 
crates/edit_prediction_context/src/syntax_index.rs                |  2 
crates/editor/benches/editor_render.rs                            |  2 
crates/editor/src/display_map.rs                                  |  2 
crates/editor/src/display_map/block_map.rs                        |  2 
crates/editor/src/display_map/fold_map.rs                         |  1 
crates/editor/src/display_map/inlay_map.rs                        |  2 
crates/editor/src/display_map/wrap_map.rs                         |  2 
crates/editor/src/editor_tests.rs                                 |  2 
crates/settings/src/settings.rs                                   |  2 
crates/settings/src/settings_registration.rs                      | 12 
crates/settings/src/settings_store.rs                             |  4 
crates/settings_macros/src/settings_macros.rs                     | 37 
crates/zeta_cli/src/headless.rs                                   |  2 
53 files changed, 150 insertions(+), 3 deletions(-)

Detailed changes

crates/acp_thread/src/acp_thread.rs 🔗

@@ -2142,6 +2142,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             Project::init_settings(cx);
             language::init(cx);
         });

crates/action_log/src/action_log.rs 🔗

@@ -1002,6 +1002,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
         });

crates/agent/src/agent_profile.rs 🔗

@@ -227,6 +227,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             Project::init_settings(cx);
             AgentSettings::register(cx);
             language_model::init_settings(cx);

crates/agent/src/context.rs 🔗

@@ -1098,6 +1098,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
         });

crates/agent/src/thread.rs 🔗

@@ -5338,6 +5338,8 @@ fn main() {{
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
             AgentSettings::register(cx);

crates/agent2/src/agent.rs 🔗

@@ -1548,6 +1548,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             Project::init_settings(cx);
             agent_settings::init(cx);
             language::init(cx);

crates/agent2/src/db.rs 🔗

@@ -437,6 +437,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             Project::init_settings(cx);
             language::init(cx);
 

crates/agent2/src/tools/edit_file_tool.rs 🔗

@@ -1737,6 +1737,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             TelemetrySettings::register(cx);
             agent_settings::AgentSettings::register(cx);

crates/agent2/src/tools/find_path_tool.rs 🔗

@@ -243,6 +243,8 @@ mod test {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
         });

crates/agent2/src/tools/grep_tool.rs 🔗

@@ -775,6 +775,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
         });

crates/agent2/src/tools/list_directory_tool.rs 🔗

@@ -231,6 +231,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
         });

crates/agent2/src/tools/open_tool.rs 🔗

@@ -163,6 +163,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
         });

crates/agent2/src/tools/read_file_tool.rs 🔗

@@ -507,6 +507,8 @@ mod test {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
         });

crates/agent_servers/src/e2e_tests.rs 🔗

@@ -459,6 +459,8 @@ pub async fn init_test(cx: &mut TestAppContext) -> Arc<FakeFs> {
     cx.update(|cx| {
         let settings_store = settings::SettingsStore::test(cx);
         cx.set_global(settings_store);
+        SettingsStore::load_registered_settings(cx);
+
         Project::init_settings(cx);
         language::init(cx);
         gpui_tokio::init(cx);

crates/agent_ui/src/acp/entry_view_state.rs 🔗

@@ -540,6 +540,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
             AgentSettings::register(cx);

crates/agent_ui/src/acp/thread_view.rs 🔗

@@ -5990,6 +5990,8 @@ pub(crate) mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
             AgentSettings::register(cx);

crates/agent_ui/src/agent_diff.rs 🔗

@@ -1826,6 +1826,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
             AgentSettings::register(cx);
@@ -1978,6 +1980,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
             AgentSettings::register(cx);

crates/agent_ui/src/buffer_codegen.rs 🔗

@@ -1468,6 +1468,8 @@ mod tests {
     fn init_test(cx: &mut TestAppContext) {
         cx.update(LanguageModelRegistry::test);
         cx.set_global(cx.update(SettingsStore::test));
+        SettingsStore::load_registered_settings(cx);
+
         cx.update(Project::init_settings);
         cx.update(language_settings::init);
     }

crates/agent_ui/src/context_picker/completion_provider.rs 🔗

@@ -1481,6 +1481,8 @@ mod tests {
         cx.update(|cx| {
             let store = SettingsStore::test(cx);
             cx.set_global(store);
+            SettingsStore::load_registered_settings(cx);
+
             theme::init(theme::LoadThemes::JustBase, cx);
             client::init_settings(cx);
             language::init(cx);

crates/agent_ui/src/text_thread_editor.rs 🔗

@@ -3217,6 +3217,8 @@ mod tests {
         prompt_store::init(cx);
         LanguageModelRegistry::test(cx);
         cx.set_global(settings_store);
+        SettingsStore::load_registered_settings(cx);
+
         language::init(cx);
         agent_settings::init(cx);
         Project::init_settings(cx);

crates/assistant_context/src/assistant_context_tests.rs 🔗

@@ -1385,6 +1385,7 @@ fn init_test(cx: &mut App) {
     prompt_store::init(cx);
     LanguageModelRegistry::test(cx);
     cx.set_global(settings_store);
+    SettingsStore::load_registered_settings(cx);
     language::init(cx);
     agent_settings::init(cx);
     Project::init_settings(cx);

crates/assistant_slash_commands/src/file_command.rs 🔗

@@ -592,6 +592,7 @@ mod test {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
             // release_channel::init(SemanticVersion::default(), cx);
             language::init(cx);
             Project::init_settings(cx);

crates/assistant_tools/src/edit_file_tool.rs 🔗

@@ -1436,6 +1436,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             TelemetrySettings::register(cx);
             agent_settings::AgentSettings::register(cx);
@@ -1450,6 +1452,8 @@ mod tests {
 
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             TelemetrySettings::register(cx);
             agent_settings::AgentSettings::register(cx);

crates/assistant_tools/src/find_path_tool.rs 🔗

@@ -457,6 +457,8 @@ mod test {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
         });

crates/assistant_tools/src/grep_tool.rs 🔗

@@ -797,6 +797,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
         });

crates/assistant_tools/src/list_directory_tool.rs 🔗

@@ -247,6 +247,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
         });

crates/assistant_tools/src/open_tool.rs 🔗

@@ -163,6 +163,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
         });

crates/assistant_tools/src/project_notifications_tool.rs 🔗

@@ -352,6 +352,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
             assistant_tool::init(cx);

crates/assistant_tools/src/read_file_tool.rs 🔗

@@ -598,6 +598,8 @@ mod test {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
         });

crates/assistant_tools/src/terminal_tool.rs 🔗

@@ -705,6 +705,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
             workspace::init_settings(cx);

crates/channel/src/channel_store_tests.rs 🔗

@@ -236,6 +236,8 @@ fn test_dangling_channel_paths(cx: &mut App) {
 fn init_test(cx: &mut App) -> Entity<ChannelStore> {
     let settings_store = SettingsStore::test(cx);
     cx.set_global(settings_store);
+    SettingsStore::load_registered_settings(cx);
+
     release_channel::init(SemanticVersion::default(), cx);
     client::init_settings(cx);
 

crates/client/src/client.rs 🔗

@@ -2202,6 +2202,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             init_settings(cx);
         });
     }

crates/client/src/telemetry.rs 🔗

@@ -836,6 +836,7 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
         });
     }
 

crates/collab/src/tests/test_server.rs 🔗

@@ -172,6 +172,8 @@ impl TestServer {
             }
             let settings = SettingsStore::test(cx);
             cx.set_global(settings);
+            SettingsStore::load_registered_settings(cx);
+
             release_channel::init(SemanticVersion::default(), cx);
             client::init_settings(cx);
         });

crates/copilot/src/copilot_completion_provider.rs 🔗

@@ -1116,6 +1116,8 @@ mod tests {
         cx.update(|cx| {
             let store = SettingsStore::test(cx);
             cx.set_global(store);
+            SettingsStore::load_registered_settings(cx);
+
             theme::init(theme::LoadThemes::JustBase, cx);
             client::init_settings(cx);
             language::init(cx);

crates/dap/src/client.rs 🔗

@@ -277,6 +277,8 @@ mod tests {
         cx.update(|cx| {
             let settings = SettingsStore::test(cx);
             cx.set_global(settings);
+            SettingsStore::load_registered_settings(cx);
+
             DebuggerSettings::register(cx);
         });
     }

crates/debugger_ui/src/tests.rs 🔗

@@ -40,6 +40,8 @@ pub fn init_test(cx: &mut gpui::TestAppContext) {
     cx.update(|cx| {
         let settings = SettingsStore::test(cx);
         cx.set_global(settings);
+        SettingsStore::load_registered_settings(cx);
+
         terminal_view::init(cx);
         theme::init(theme::LoadThemes::JustBase, cx);
         command_palette_hooks::init(cx);

crates/diagnostics/src/diagnostics_tests.rs 🔗

@@ -2006,6 +2006,8 @@ fn init_test(cx: &mut TestAppContext) {
         zlog::init_test();
         let settings = SettingsStore::test(cx);
         cx.set_global(settings);
+        SettingsStore::load_registered_settings(cx);
+
         theme::init(theme::LoadThemes::JustBase, cx);
         language::init(cx);
         client::init_settings(cx);

crates/edit_prediction_context/src/syntax_index.rs 🔗

@@ -755,6 +755,8 @@ mod tests {
         cx.update(|cx| {
             let settings_store = SettingsStore::test(cx);
             cx.set_global(settings_store);
+            SettingsStore::load_registered_settings(cx);
+
             language::init(cx);
             Project::init_settings(cx);
         });

crates/editor/benches/editor_render.rs 🔗

@@ -122,6 +122,8 @@ pub fn benches() {
     cx.update(|cx| {
         let store = SettingsStore::test(cx);
         cx.set_global(store);
+        SettingsStore::load_registered_settings(cx);
+
         assets::Assets.load_test_fonts(cx);
         theme::init(theme::LoadThemes::JustBase, cx);
         // release_channel::init(SemanticVersion::default(), cx);

crates/editor/src/display_map.rs 🔗

@@ -2919,6 +2919,8 @@ pub mod tests {
     fn init_test(cx: &mut App, f: impl Fn(&mut SettingsContent)) {
         let settings = SettingsStore::test(cx);
         cx.set_global(settings);
+        SettingsStore::load_registered_settings(cx);
+
         workspace::init_settings(cx);
         language::init(cx);
         crate::init(cx);

crates/editor/src/display_map/block_map.rs 🔗

@@ -3569,6 +3569,8 @@ mod tests {
     fn init_test(cx: &mut gpui::App) {
         let settings = SettingsStore::test(cx);
         cx.set_global(settings);
+        SettingsStore::load_registered_settings(cx);
+
         theme::init(theme::LoadThemes::JustBase, cx);
         assets::Assets.load_test_fonts(cx);
     }

crates/editor/src/display_map/fold_map.rs 🔗

@@ -2193,6 +2193,7 @@ mod tests {
     fn init_test(cx: &mut gpui::App) {
         let store = SettingsStore::test(cx);
         cx.set_global(store);
+        SettingsStore::load_registered_settings(cx);
     }
 
     impl FoldMap {

crates/editor/src/display_map/inlay_map.rs 🔗

@@ -2102,6 +2102,8 @@ mod tests {
     fn init_test(cx: &mut App) {
         let store = SettingsStore::test(cx);
         cx.set_global(store);
+        SettingsStore::load_registered_settings(cx);
+
         theme::init(theme::LoadThemes::JustBase, cx);
     }
 

crates/editor/src/display_map/wrap_map.rs 🔗

@@ -1460,6 +1460,8 @@ mod tests {
         cx.update(|cx| {
             let settings = SettingsStore::test(cx);
             cx.set_global(settings);
+            SettingsStore::load_registered_settings(cx);
+
             theme::init(LoadThemes::JustBase, cx);
         });
     }

crates/editor/src/editor_tests.rs 🔗

@@ -25128,6 +25128,8 @@ pub(crate) fn init_test(cx: &mut TestAppContext, f: fn(&mut AllLanguageSettingsC
         assets::Assets.load_test_fonts(cx);
         let store = SettingsStore::test(cx);
         cx.set_global(store);
+        SettingsStore::load_registered_settings(cx);
+
         theme::init(theme::LoadThemes::JustBase, cx);
         release_channel::init(SemanticVersion::default(), cx);
         client::init_settings(cx);

crates/settings/src/settings.rs 🔗

@@ -5,10 +5,10 @@ pub mod merge_from;
 mod settings_content;
 mod settings_file;
 mod settings_json;
+pub mod settings_registration;
 mod settings_store;
 mod settings_ui_core;
 mod vscode_import;
-
 pub use settings_content::*;
 
 use gpui::{App, Global};

crates/settings/src/settings_registration.rs 🔗

@@ -0,0 +1,12 @@
+use gpui::App;
+pub use inventory;
+
+pub struct RegisterSettingFn(fn(&mut App));
+
+inventory::collect!(RegisterSettingFn);
+
+pub fn load_registered_settings(cx: &mut App) {
+    for register_function in inventory::iter::<RegisterSettingFn> {
+        (register_function.0)(cx);
+    }
+}

crates/settings/src/settings_store.rs 🔗

@@ -235,6 +235,10 @@ impl SettingsStore {
         }
     }
 
+    pub fn load_registered_settings(cx: &mut App) {
+        crate::settings_registration::load_registered_settings(cx);
+    }
+
     pub fn observe_active_settings_profile_name(cx: &mut App) -> gpui::Subscription {
         cx.observe_global::<ActiveSettingsProfileName>(|cx| {
             Self::update_global(cx, |store, cx| {

crates/settings_macros/src/settings_macros.rs 🔗

@@ -1,6 +1,6 @@
 use proc_macro::TokenStream;
-use quote::quote;
-use syn::{Data, DeriveInput, Fields, parse_macro_input};
+use quote::{format_ident, quote};
+use syn::{Data, DeriveInput, Fields, Ident, parse_macro_input};
 
 /// Derives the `MergeFrom` trait for a struct.
 ///
@@ -76,3 +76,36 @@ pub fn derive_merge_from(input: TokenStream) -> TokenStream {
 
     TokenStream::from(expanded)
 }
+
+/// This can be used to register an action with the GPUI runtime when you want to manually implement
+/// the `Action` trait. Typically you should use the `Action` derive macro or `actions!` macro
+/// instead.
+#[proc_macro_derive(RegisterSetting)]
+pub fn register_settings(ident: TokenStream) -> TokenStream {
+    let type_name = parse_macro_input!(ident as Ident);
+
+    let settings_registration_fn_name = format_ident!(
+        "__settings_registration_{}",
+        type_name.to_string().to_lowercase()
+    );
+
+    quote! {
+        impl #type_name {
+            /// This is an auto generated function, do not use.
+            #[automatically_derived]
+            #[doc(hidden)]
+            fn __autogenerated() {
+                /// This is an auto generated function, do not use.
+                #[doc(hidden)]
+                fn #settings_registration_fn_name(cx: &mut gpui::AppContext) {
+                    #type_name::register(cx);
+                }
+
+                settings::settings_registration::inventory::submit! {
+                    settings::settings_registration::RegisterSettingFn(#settings_registration_fn_name)
+                }
+            }
+        }
+    }
+    .into()
+}

crates/zeta_cli/src/headless.rs 🔗

@@ -33,6 +33,8 @@ pub fn init(cx: &mut App) -> ZetaCliAppState {
 
     let settings_store = SettingsStore::new(cx, &settings::default_settings());
     cx.set_global(settings_store);
+    SettingsStore::load_registered_settings(cx);
+
     client::init_settings(cx);
 
     // Set User-Agent so we can download language servers from GitHub